label.hh

00001 // This file is a part of Aurelia.
00002 // Copyright (C) 2010  Valentin David
00003 // Copyright (C) 2010  University of Bergen
00004 //
00005 // This program is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00017 
00018 #ifndef __LABEL_HH
00019 # define __LABEL_HH
00020 # include <cassert>
00021 # include "frame.hh"
00022 # include "../streams/buf_stream.hh"
00023 # include "../hash/hash_addr.hh"
00024 
00025 namespace aurelia {
00026   namespace llstack {
00027 
00028 struct node;
00029 struct r_t;
00030 
00031 struct label {
00032 private:
00033   std::function<void(r_t&, const frame&, stream&, const node&)> fun;
00034   size_t type;
00035 
00036 public:
00037   template <typename T>
00038   label(const T& in): fun(in), type((size_t)&typeid(T)) {}
00039 
00040   label(const label& other): fun(other.fun), type(other.type) {
00041   }
00042 
00043   label(label&& other): fun(std::move(other.fun)), type(other.type) {}
00044 
00045   label() {
00046   }
00047 
00048   void call(r_t& R, const frame& f, stream& s, const node& n) const {
00049     fun(R, f, s, n);
00050   }
00051 
00052   unsigned hash() const {
00053     return std::hash<size_t>()(type);
00054   }
00055 
00056   label& operator=(const label& other) {
00057     return *this = label(other);
00058   }
00059 
00060   label& operator=(label&& other) {
00061     std::swap(fun, other.fun);
00062     std::swap(type, other.type);
00063     return *this;
00064   }
00065 
00066   bool operator==(const label& other) const {
00067     return (type == other.type);
00068   }
00069 };
00070 
00071   }
00072 }
00073 
00074 #endif