| ////////////////////////////////////////////////////////////////////////////// |
| // |
| // (C) Copyright Ion Gaztanaga 2012-2012. |
| // Distributed under the Boost Software License, Version 1.0. |
| // (See accompanying file LICENSE_1_0.txt or copy at |
| // http://www.boost.org/LICENSE_1_0.txt) |
| // |
| // See http://www.boost.org/libs/move for documentation. |
| // |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| //! \file |
| |
| #ifndef NDNBOOST_MOVE_DETAIL_META_UTILS_HPP |
| #define NDNBOOST_MOVE_DETAIL_META_UTILS_HPP |
| |
| #include <ndnboost/move/detail/config_begin.hpp> |
| |
| //Small meta-typetraits to support move |
| |
| namespace ndnboost { |
| namespace move_detail { |
| |
| //if_ |
| template<bool C, typename T1, typename T2> |
| struct if_c |
| { |
| typedef T1 type; |
| }; |
| |
| template<typename T1, typename T2> |
| struct if_c<false,T1,T2> |
| { |
| typedef T2 type; |
| }; |
| |
| template<typename T1, typename T2, typename T3> |
| struct if_ |
| { |
| typedef typename if_c<0 != T1::value, T2, T3>::type type; |
| }; |
| |
| //enable_if_ |
| template <bool B, class T = void> |
| struct enable_if_c |
| { |
| typedef T type; |
| }; |
| |
| template <class T> |
| struct enable_if_c<false, T> {}; |
| |
| template <class Cond, class T = void> |
| struct enable_if : public enable_if_c<Cond::value, T> {}; |
| |
| template <class Cond, class T = void> |
| struct disable_if : public enable_if_c<!Cond::value, T> {}; |
| |
| //integral_constant |
| template<class T, T v> |
| struct integral_constant |
| { |
| static const T value = v; |
| typedef T value_type; |
| typedef integral_constant<T, v> type; |
| }; |
| |
| //identity |
| template <class T> |
| struct identity |
| { |
| typedef T type; |
| }; |
| |
| //is_convertible |
| template <class T, class U> |
| class is_convertible |
| { |
| typedef char true_t; |
| class false_t { char dummy[2]; }; |
| static true_t dispatch(U); |
| static false_t dispatch(...); |
| static T &trigger(); |
| public: |
| enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) }; |
| }; |
| |
| //and_ not_ |
| template <typename Condition1, typename Condition2, typename Condition3 = integral_constant<bool, true> > |
| struct and_ |
| : public integral_constant<bool, Condition1::value && Condition2::value && Condition3::value> |
| {}; |
| |
| template <typename Boolean> |
| struct not_ |
| : public integral_constant<bool, !Boolean::value> |
| {}; |
| |
| //is_lvalue_reference |
| template<class T> |
| struct is_lvalue_reference |
| : public integral_constant<bool, false> |
| {}; |
| |
| template<class T> |
| struct is_lvalue_reference<T&> |
| : public integral_constant<bool, true> |
| {}; |
| |
| template<class T> |
| struct is_class_or_union |
| { |
| struct twochar { char _[2]; }; |
| template <class U> |
| static char is_class_or_union_tester(void(U::*)(void)); |
| template <class U> |
| static twochar is_class_or_union_tester(...); |
| static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char); |
| }; |
| |
| struct empty{}; |
| |
| //addressof |
| template<class T> struct addr_impl_ref |
| { |
| T & v_; |
| inline addr_impl_ref( T & v ): v_( v ) {} |
| inline operator T& () const { return v_; } |
| |
| private: |
| addr_impl_ref & operator=(const addr_impl_ref &); |
| }; |
| |
| template<class T> struct addressof_impl |
| { |
| static inline T * f( T & v, long ) |
| { |
| return reinterpret_cast<T*>( |
| &const_cast<char&>(reinterpret_cast<const volatile char &>(v))); |
| } |
| |
| static inline T * f( T * v, int ) |
| { return v; } |
| }; |
| |
| template<class T> |
| inline T * addressof( T & v ) |
| { |
| return ::ndnboost::move_detail::addressof_impl<T>::f |
| ( ::ndnboost::move_detail::addr_impl_ref<T>( v ), 0 ); |
| } |
| |
| } //namespace move_detail { |
| } //namespace ndnboost { |
| |
| #include <ndnboost/move/detail/config_end.hpp> |
| |
| #endif //#ifndef NDNBOOST_MOVE_DETAIL_META_UTILS_HPP |