blob: 1f68fb2d69d554814581932466e10646c2c5629c [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2012-2012.
4// Distributed under the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at
6// http://www.boost.org/LICENSE_1_0.txt)
7//
8// See http://www.boost.org/libs/move for documentation.
9//
10//////////////////////////////////////////////////////////////////////////////
11
12//! \file
13
14#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP
15#define BOOST_MOVE_DETAIL_META_UTILS_HPP
16
17#include <ndnboost/move/detail/config_begin.hpp>
18
19//Small meta-typetraits to support move
20
21namespace ndnboost {
22namespace move_detail {
23
24//if_
25template<bool C, typename T1, typename T2>
26struct if_c
27{
28 typedef T1 type;
29};
30
31template<typename T1, typename T2>
32struct if_c<false,T1,T2>
33{
34 typedef T2 type;
35};
36
37template<typename T1, typename T2, typename T3>
38struct if_
39{
40 typedef typename if_c<0 != T1::value, T2, T3>::type type;
41};
42
43//enable_if_
44template <bool B, class T = void>
45struct enable_if_c
46{
47 typedef T type;
48};
49
50template <class T>
51struct enable_if_c<false, T> {};
52
53template <class Cond, class T = void>
54struct enable_if : public enable_if_c<Cond::value, T> {};
55
56template <class Cond, class T = void>
57struct disable_if : public enable_if_c<!Cond::value, T> {};
58
59//integral_constant
60template<class T, T v>
61struct integral_constant
62{
63 static const T value = v;
64 typedef T value_type;
65 typedef integral_constant<T, v> type;
66};
67
68//identity
69template <class T>
70struct identity
71{
72 typedef T type;
73};
74
75//is_convertible
76template <class T, class U>
77class is_convertible
78{
79 typedef char true_t;
80 class false_t { char dummy[2]; };
81 static true_t dispatch(U);
82 static false_t dispatch(...);
83 static T &trigger();
84 public:
85 enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
86};
87
88//and_ not_
89template <typename Condition1, typename Condition2, typename Condition3 = integral_constant<bool, true> >
90struct and_
91 : public integral_constant<bool, Condition1::value && Condition2::value && Condition3::value>
92{};
93
94template <typename Boolean>
95struct not_
96 : public integral_constant<bool, !Boolean::value>
97{};
98
99//is_lvalue_reference
100template<class T>
101struct is_lvalue_reference
102 : public integral_constant<bool, false>
103{};
104
105template<class T>
106struct is_lvalue_reference<T&>
107 : public integral_constant<bool, true>
108{};
109
110template<class T>
111struct is_class_or_union
112{
113 struct twochar { char _[2]; };
114 template <class U>
115 static char is_class_or_union_tester(void(U::*)(void));
116 template <class U>
117 static twochar is_class_or_union_tester(...);
118 static const bool value = sizeof(is_class_or_union_tester<T>(0)) == sizeof(char);
119};
120
121struct empty{};
122
123//addressof
124template<class T> struct addr_impl_ref
125{
126 T & v_;
127 inline addr_impl_ref( T & v ): v_( v ) {}
128 inline operator T& () const { return v_; }
129
130 private:
131 addr_impl_ref & operator=(const addr_impl_ref &);
132};
133
134template<class T> struct addressof_impl
135{
136 static inline T * f( T & v, long )
137 {
138 return reinterpret_cast<T*>(
139 &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
140 }
141
142 static inline T * f( T * v, int )
143 { return v; }
144};
145
146template<class T>
147inline T * addressof( T & v )
148{
149 return ::ndnboost::move_detail::addressof_impl<T>::f
150 ( ::ndnboost::move_detail::addr_impl_ref<T>( v ), 0 );
151}
152
153} //namespace move_detail {
154} //namespace ndnboost {
155
156#include <ndnboost/move/detail/config_end.hpp>
157
158#endif //#ifndef BOOST_MOVE_DETAIL_META_UTILS_HPP