|
iLab Neuromorphic Robotics Toolkit
0.1
|
00001 /*! @file 00002 @author David J. Berg (dberg@usc.edu) 00003 @copyright GNU Public License (GPL v3) 00004 @section License 00005 @verbatim 00006 // //////////////////////////////////////////////////////////////////////// 00007 // The iLab Neuromorphic Robotics Toolkit (NRT) // 00008 // Copyright 2010-2012 by the University of Southern California (USC) // 00009 // and the iLab at USC. // 00010 // // 00011 // iLab - University of Southern California // 00012 // Hedco Neurociences Building, Room HNB-10 // 00013 // Los Angeles, Ca 90089-2520 - USA // 00014 // // 00015 // See http://ilab.usc.edu for information about this project. // 00016 // //////////////////////////////////////////////////////////////////////// 00017 // This file is part of The iLab Neuromorphic Robotics Toolkit. // 00018 // // 00019 // The iLab Neuromorphic Robotics Toolkit is free software: you can // 00020 // redistribute it and/or modify it under the terms of the GNU General // 00021 // Public License as published by the Free Software Foundation, either // 00022 // version 3 of the License, or (at your option) any later version. // 00023 // // 00024 // The iLab Neuromorphic Robotics Toolkit is distributed in the hope // 00025 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00026 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00027 // PURPOSE. See the GNU General Public License for more details. // 00028 // // 00029 // You should have received a copy of the GNU General Public License // 00030 // along with The iLab Neuromorphic Robotics Toolkit. If not, see // 00031 // <http://www.gnu.org/licenses/>. // 00032 // //////////////////////////////////////////////////////////////////////// 00033 @endverbatim */ 00034 00035 00036 #ifndef INCLUDE_NRT_CORE_TYPING_DETAILS_TYPETRAITSHELPERS_H 00037 #define INCLUDE_NRT_CORE_TYPING_DETAILS_TYPETRAITSHELPERS_H 00038 00039 namespace nrt 00040 { 00041 //! A set of type trait class to check if two types can be used in an arithmetic operation, or compared 00042 /*! 00043 See nrt::nrt_traits on how to use the function_existence_helper. The namespace supports classes which can be 00044 derived from to perform compile time checks for functions which take one or two arguments. 00045 */ 00046 namespace function_existence_helper 00047 { 00048 // A type returned by the binary operator for any struct in this namespace 00049 // where T does not support the operator. 00050 struct no_support {}; 00051 00052 // These types soaks up any implicit conversions and makes the following 00053 // binary operator less preferred than any other such operator found duirng 00054 // the argument dependent lookup (ADL) 00055 struct any_class1 { template <class T> any_class1(T const&); };//can convert any type 00056 struct any_class2 { template <class T> any_class2(T const&); };//can convert any type 00057 00058 // Fallback operators for when the binary operator for types T are not supported 00059 // use a macro here to help us define them for a bunch of operators 00060 no_support operator == (any_class1 const&, any_class2 const&); 00061 no_support operator < (any_class1 const&, any_class2 const&); 00062 no_support operator <= (any_class1 const&, any_class2 const&); 00063 no_support operator > (any_class1 const&, any_class2 const&); 00064 no_support operator >= (any_class1 const&, any_class2 const&); 00065 00066 no_support operator + (any_class1 const&, any_class2 const&); 00067 no_support operator - (any_class1 const&, any_class2 const&); 00068 no_support operator * (any_class1 const&, any_class2 const&); 00069 no_support operator / (any_class1 const&, any_class2 const&); 00070 no_support operator += (any_class1 const&, any_class2 const&); 00071 no_support operator -= (any_class1 const&, any_class2 const&); 00072 no_support operator *= (any_class1 const&, any_class2 const&); 00073 no_support operator /= (any_class1 const&, any_class2 const&); 00074 00075 // Two typedefs overloads to distinguish whether T supports a certain operator 00076 // expression. The first typedef is a reference to a two-element character 00077 // array and is chosen if T does not support the expression. The second 00078 // overload returns a char and is chosen if T supports the expression. So 00079 // using sizeof(check(<expression>)) returns 2 for the first overload and 1 00080 // for the second overload. 00081 typedef char (&no)[2]; 00082 typedef char yes; 00083 00084 no check(no_support); 00085 template <class T> yes check(T const&);//this will be a bool most likely if an operator is found 00086 00087 // Implementation for equality template metafunction. 00088 template <class T ,class U> 00089 struct is_equality_comparable_impl 00090 { 00091 static typename std::remove_cv<typename std::remove_reference<T>::type>::type const& x; 00092 static typename std::remove_cv<typename std::remove_reference<U>::type>::type const& y; 00093 static const bool value = sizeof(check( x == y )) == sizeof(yes) && sizeof(check( y == x )) == sizeof(yes); 00094 }; 00095 00096 // Implementation for all comparisons template metafunction. 00097 template <class T ,class U> 00098 struct is_comparable_impl 00099 { 00100 static typename std::remove_cv<typename std::remove_reference<T>::type>::type const& x; 00101 static typename std::remove_cv<typename std::remove_reference<U>::type>::type const& y; 00102 static const bool value = sizeof(check( x == y )) == sizeof(yes) && sizeof(check( y == x )) == sizeof(yes) && 00103 sizeof(check( x < y )) == sizeof(yes) && sizeof(check( y < x )) == sizeof(yes) && 00104 sizeof(check( x > y )) == sizeof(yes) && sizeof(check( y > x )) == sizeof(yes) && 00105 sizeof(check( x <= y )) == sizeof(yes) && sizeof(check( y <= x )) == sizeof(yes) && 00106 sizeof(check( x >= y )) == sizeof(yes) && sizeof(check( y >= x )) == sizeof(yes); 00107 }; 00108 00109 // Implementation for operable template metafunction. 00110 template <class T ,class U> 00111 struct has_arithmetic_impl 00112 { 00113 static typename std::remove_cv<typename std::remove_reference<T>::type>::type const& x; 00114 static typename std::remove_cv<typename std::remove_reference<U>::type>::type const& y; 00115 static const bool value = sizeof(check( x + y )) == sizeof(yes) && sizeof(check( y + x )) == sizeof(yes) && 00116 sizeof(check( x - y )) == sizeof(yes) && sizeof(check( y - x )) == sizeof(yes) && 00117 sizeof(check( x * y )) == sizeof(yes) && sizeof(check( y * x )) == sizeof(yes) && 00118 sizeof(check( x / y )) == sizeof(yes) && sizeof(check( y / x )) == sizeof(yes); 00119 }; 00120 00121 // Implementation for assign_operable template metafunction. 00122 template <class T ,class U> 00123 struct has_assign_arithmetic_impl 00124 { 00125 static typename std::remove_cv<typename std::remove_reference<T>::type>::type & x; 00126 static typename std::remove_cv<typename std::remove_reference<U>::type>::type & y; 00127 static const bool value = sizeof(check( x += y )) == sizeof(yes) && 00128 sizeof(check( x -= y )) == sizeof(yes) && 00129 sizeof(check( x *= y )) == sizeof(yes) && 00130 sizeof(check( x /= y )) == sizeof(yes); 00131 }; 00132 00133 // Implementation for promotable template metafunction. 00134 template <class T ,class U> 00135 struct is_promotable_impl 00136 { 00137 static typename std::remove_cv<typename std::remove_reference<T>::type>::type const& x; 00138 static typename std::remove_cv<typename std::remove_reference<U>::type>::type const& y; 00139 static const bool value = sizeof(check( x * y )) == sizeof(yes) && sizeof(check( y * x )) == sizeof(yes); 00140 }; 00141 } 00142 00143 //define some type_traits 00144 template <class T, class U> 00145 struct is_equality_comparable : function_existence_helper::is_equality_comparable_impl<T,U> {}; 00146 template <class T, class U> struct is_equality_comparable<T*,U*> { static const bool value = 0; }; 00147 template <class T> struct is_equality_comparable<T,void> { static const bool value = 0; }; 00148 template <class U> struct is_equality_comparable<void,U> { static const bool value = 0; }; 00149 template <> struct is_equality_comparable<void, void> { static const bool value = 0; }; 00150 00151 template <class T, class U> 00152 struct is_comparable : function_existence_helper::is_comparable_impl<T,U> {}; 00153 template <class T, class U> struct is_comparable<T*,U*> { static const bool value = 0; }; 00154 template <class T> struct is_comparable<T,void> { static const bool value = 0; }; 00155 template <class U> struct is_comparable<void,U> { static const bool value = 0; }; 00156 template <> struct is_comparable<void, void> { static const bool value = 0; }; 00157 00158 template <class T, class U> 00159 struct has_arithmetic : function_existence_helper::has_arithmetic_impl<T,U> {}; 00160 template <class T, class U> struct has_arithmetic<T*,U*> { static const bool value = 0; }; 00161 template <class T> struct has_arithmetic<T,void> { static const bool value = 0; }; 00162 template <class U> struct has_arithmetic<void, U> { static const bool value = 0; }; 00163 template <> struct has_arithmetic<void, void> { static const bool value = 0; }; 00164 00165 template <class T, class U> 00166 struct has_assign_arithmetic : function_existence_helper::has_assign_arithmetic_impl<T,U> {}; 00167 template <class T, class U> struct has_assign_arithmetic<T*,U*> { static const bool value = 0; }; 00168 template <class T> struct has_assign_arithmetic<T,void> { static const bool value = 0; }; 00169 template <class U> struct has_assign_arithmetic<void,U> { static const bool value = 0; }; 00170 template <> struct has_assign_arithmetic<void, void> { static const bool value = 0; }; 00171 00172 template <class T, class U> 00173 struct is_promotable : function_existence_helper::is_promotable_impl<T,U> {}; 00174 template <class T, class U> struct is_promotable<T*,U*> { static const bool value = 0; }; 00175 template <class T> struct is_promotable<T,void> { static const bool value = 0; }; 00176 template <class U> struct is_promotable<void,U> { static const bool value = 0; }; 00177 template <> struct is_promotable<void, void> { static const bool value = 0; }; 00178 } 00179 00180 #endif // INCLUDE_NRT_CORE_TYPING_DETAILS_TYPETRAITSHELPERS_H