constant.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 #ifndef __CONSTANT_HH
00018 # define __CONSTANT_HH
00019 
00020 # include "pattern.hh"
00021 //# include "../lists/listable.hh"
00022 
00023 namespace aurelia {
00024 
00025   template <typename T>
00026   struct constant {
00027   private:
00028     T value;
00029 
00030   public:
00031     constant() = delete;
00032     constant(const constant& v): value(v.value) {
00033     }
00034 
00035     constant(constant&& v): value(std::move(v.value)) {
00036     }
00037 
00038     constant(const T& v): value(v) {
00039     }
00040 
00041     constant(T&& v): value(std::move(v)) {
00042     }
00043 
00044     template <typename U,
00045               typename = typename
00046               std::enable_if<std::is_convertible<U, T>::value>::type>
00047     constant(const U& v): value(v) {}
00048 
00049     template <typename U,
00050               typename = typename
00051               std::enable_if<std::is_convertible<U, T>::value>::type>
00052     constant(U&& v): value(std::move(v)) {}
00053 
00054     const T& operator*() const {
00055       return value;
00056     }
00057 
00058     const T& operator=(const T& c) const {
00059       if (value != c)
00060         throw failure();
00061       return value;
00062     }
00063 
00064   };
00065 
00068   template <typename T>
00069   struct pattern_model<constant<T> > {
00070     struct model {
00071       typedef constant<T> type;
00072       typedef T build_type;
00073     };
00074   };
00075 
00076   template <typename T>
00077   struct listable_model<constant<T> > {
00078     struct model {
00079       typedef constant<T> type;
00080     };
00081   };
00082 
00083 }
00084 
00085 #endif