wrappers/operators.hh

00001 // This file is a part of Catsfoot.
00002 // Copyright (C) 2011  Uni Research
00003 //
00004 // This program is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #ifndef OPERATORS_HH
00018 # define OPERATORS_HH
00019 
00020 # include "../type_traits/is_constructible.hh"
00021 
00022 namespace catsfoot {
00023 
00026 
00028   struct op_eq {
00029     template <typename T, typename U,
00030               typename Ret = decltype(std::declval<T>() == std::declval<U>())>
00031     Ret operator()(T&& t, U&& u) const {
00032       return std::forward<T>(t) == std::forward<U>(u);
00033     }
00034   };
00035 
00037   struct op_neq {
00038     template <typename T, typename U,
00039               typename Ret = decltype(std::declval<T>() != std::declval<U>())>
00040     Ret operator()(T&& t, U&& u) const {
00041       return std::forward<T>(t) != std::forward<U>(u);
00042     }
00043   };
00044 
00046   struct op_plus {
00047     template <typename T, typename U,
00048               typename Ret = decltype(std::declval<T>() + std::declval<U>())>
00049     Ret operator()(T&& t, U&& u) const {
00050       return std::forward<T>(t) + std::forward<U>(u);
00051     }
00052   };
00053 
00055   struct op_times {
00056     template <typename T, typename U,
00057               typename Ret = decltype(std::declval<T>() * std::declval<U>())>
00058     Ret operator()(T&& t, U&& u) const {
00059       return std::forward<T>(t) * std::forward<U>(u);
00060     }
00061   };
00062 
00064   struct op_lsh {
00065     template <typename T, typename U,
00066               typename Ret = decltype(std::declval<T>() << std::declval<U>())>
00067     Ret operator()(T&& t, U&& u) const {
00068       return t << std::forward<U>(u);
00069     }
00070   };
00071 
00073   struct op_lt {
00074     template <typename T, typename U,
00075               typename Ret = decltype(std::declval<T>() < std::declval<U>())>
00076     Ret operator()(T&& t, U&& u) const {
00077       return t < std::forward<U>(u);
00078     }
00079   };
00080 
00082   struct op_inc {
00083     template <typename T,
00084               typename Ret = decltype(++std::declval<T>())>
00085     Ret operator()(T&& t) const {
00086       return ++std::forward<T>(t);
00087     }
00088   };
00089 
00091   struct op_post_inc {
00092     template <typename T,
00093               typename Ret = decltype(++std::declval<T>())>
00094     Ret operator()(T&& t) const {
00095       return ++std::forward<T>(t);
00096     }
00097   };
00098 
00100   struct op_star {
00101     template <typename T,
00102               typename Ret = decltype(*std::declval<T>())>
00103     Ret operator()(T&& t) const {
00104       return *std::forward<T>(t);
00105     }
00106   };
00107 
00109 
00110   namespace details {
00111     template <typename T, bool = is_constructible<T>::value>
00112     struct wrapped_constructor;
00113 
00115     template <typename T, typename... Args>
00116     struct wrapped_constructor<T(Args...), true> {
00117       T operator()(Args... args...) const {
00118         return T(std::forward<Args>(args)...);
00119       }
00120     };
00121 
00123     template <typename T, typename... Args>
00124     struct wrapped_constructor<T(Args...), false> {
00125     };
00126   }
00127 
00130   template <typename T>
00131   struct wrapped_constructor: public details::wrapped_constructor<T> {
00132   };
00133 
00134 }
00135 
00136 #endif