Skip to content

Commit 4f9c2b6

Browse files
committed
-> Added new meta-utils that were duplicated in Container & Intrusive.
-> Use some of them to avoid SFINAE instantiation errors in some old compilers. -> Added a macro to static_cast or reinterpret_cast to rv<T> so in the future we can avoid some sanitizer errors when using static_cast
1 parent 0ebc3f4 commit 4f9c2b6

File tree

6 files changed

+335
-88
lines changed

6 files changed

+335
-88
lines changed

include/boost/move/core.hpp

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@
5353

5454
#include <boost/move/detail/type_traits.hpp>
5555

56+
#if 1
57+
#define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) static_cast<RV_TYPE>(ARG)
58+
#else
59+
#define BOOST_MOVE_TO_RV_CAST(RV_TYPE, ARG) reinterpret_cast<RV_TYPE>(ARG)
60+
#endif
61+
5662
//Move emulation rv breaks standard aliasing rules so add workarounds for some compilers
5763
#if defined(__GNUC__) && (__GNUC__ >= 4) && \
5864
(\
@@ -101,6 +107,12 @@
101107
: integral_constant<bool, ::boost::move_detail::is_rv_impl<T>::value >
102108
{};
103109

110+
template <class T>
111+
struct is_not_rv
112+
{
113+
static const bool value = !is_rv<T>::value;
114+
};
115+
104116
} //namespace move_detail {
105117

106118
//////////////////////////////////////////////////////////////////////////////
@@ -113,6 +125,12 @@
113125
: ::boost::move_detail::has_move_emulation_enabled_impl<T>
114126
{};
115127

128+
template<class T>
129+
struct has_move_emulation_disabled
130+
{
131+
static const bool value = !::boost::move_detail::has_move_emulation_enabled_impl<T>::value;
132+
};
133+
116134
} //namespace boost {
117135

118136
#define BOOST_RV_REF(TYPE)\
@@ -183,7 +201,7 @@
183201
, ::boost::rv<T>&>::type
184202
move_return(T& x) BOOST_NOEXCEPT
185203
{
186-
return *static_cast< ::boost::rv<T>* >(::boost::move_detail::addressof(x));
204+
return *BOOST_MOVE_TO_RV_CAST(::boost::rv<T>*, ::boost::move_detail::addressof(x));
187205
}
188206

189207
template <class Ret, class T>
@@ -216,9 +234,9 @@
216234
BOOST_MOVE_IMPL_NO_COPY_CTOR_OR_ASSIGN(TYPE)\
217235
public:\
218236
operator ::boost::rv<TYPE>&() \
219-
{ return *static_cast< ::boost::rv<TYPE>* >(this); }\
237+
{ return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this); }\
220238
operator const ::boost::rv<TYPE>&() const \
221-
{ return *static_cast<const ::boost::rv<TYPE>* >(this); }\
239+
{ return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this); }\
222240
private:\
223241
//
224242

@@ -231,21 +249,21 @@
231249
#define BOOST_COPYABLE_AND_MOVABLE(TYPE)\
232250
public:\
233251
TYPE& operator=(TYPE &t)\
234-
{ this->operator=(static_cast<const ::boost::rv<TYPE> &>(const_cast<const TYPE &>(t))); return *this;}\
252+
{ this->operator=(const_cast<const TYPE &>(t)); return *this;}\
235253
public:\
236254
operator ::boost::rv<TYPE>&() \
237-
{ return *static_cast< ::boost::rv<TYPE>* >(this); }\
255+
{ return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this); }\
238256
operator const ::boost::rv<TYPE>&() const \
239-
{ return *static_cast<const ::boost::rv<TYPE>* >(this); }\
257+
{ return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this); }\
240258
private:\
241259
//
242260

243261
#define BOOST_COPYABLE_AND_MOVABLE_ALT(TYPE)\
244262
public:\
245263
operator ::boost::rv<TYPE>&() \
246-
{ return *static_cast< ::boost::rv<TYPE>* >(this); }\
264+
{ return *BOOST_MOVE_TO_RV_CAST(::boost::rv<TYPE>*, this); }\
247265
operator const ::boost::rv<TYPE>&() const \
248-
{ return *static_cast<const ::boost::rv<TYPE>* >(this); }\
266+
{ return *BOOST_MOVE_TO_RV_CAST(const ::boost::rv<TYPE>*, this); }\
249267
private:\
250268
//
251269

@@ -295,6 +313,12 @@
295313
static const bool value = false;
296314
};
297315

316+
template<class T>
317+
struct has_move_emulation_disabled
318+
{
319+
static const bool value = true;
320+
};
321+
298322
} //namespace boost{
299323

300324
//!This macro is used to achieve portable syntax in move

include/boost/move/detail/meta_utils.hpp

Lines changed: 194 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,53 @@ template <class T> class rv;
3333

3434
namespace move_detail {
3535

36+
//////////////////////////////////////
37+
// is_different
38+
//////////////////////////////////////
39+
template<class T, class U>
40+
struct is_different
41+
{
42+
static const bool value = !is_same<T, U>::value;
43+
};
44+
45+
//////////////////////////////////////
46+
// apply
47+
//////////////////////////////////////
48+
template<class F, class Param>
49+
struct apply
50+
{
51+
typedef typename F::template apply<Param>::type type;
52+
};
53+
54+
//////////////////////////////////////
55+
// bool_
56+
//////////////////////////////////////
57+
58+
template< bool C_ >
59+
struct bool_ : integral_constant<bool, C_>
60+
{
61+
operator bool() const { return C_; }
62+
bool operator()() const { return C_; }
63+
};
64+
65+
typedef bool_<true> true_;
66+
typedef bool_<false> false_;
67+
3668
//////////////////////////////////////
3769
// nat
3870
//////////////////////////////////////
3971
struct nat{};
4072

73+
//////////////////////////////////////
74+
// yes_type/no_type
75+
//////////////////////////////////////
76+
typedef char yes_type;
77+
78+
struct no_type
79+
{
80+
char _[2];
81+
};
82+
4183
//////////////////////////////////////
4284
// natify
4385
//////////////////////////////////////
@@ -86,9 +128,27 @@ struct remove_reference< const rv<T> &>
86128
typedef T type;
87129
};
88130

89-
90131
#endif
91132

133+
//////////////////////////////////////
134+
// remove_pointer
135+
//////////////////////////////////////
136+
137+
template< class T > struct remove_pointer { typedef T type; };
138+
template< class T > struct remove_pointer<T*> { typedef T type; };
139+
template< class T > struct remove_pointer<T* const> { typedef T type; };
140+
template< class T > struct remove_pointer<T* volatile> { typedef T type; };
141+
template< class T > struct remove_pointer<T* const volatile> { typedef T type; };
142+
143+
//////////////////////////////////////
144+
// add_pointer
145+
//////////////////////////////////////
146+
template< class T >
147+
struct add_pointer
148+
{
149+
typedef typename remove_reference<T>::type* type;
150+
};
151+
92152
//////////////////////////////////////
93153
// add_const
94154
//////////////////////////////////////
@@ -151,6 +211,19 @@ struct is_lvalue_reference<T&>
151211
static const bool value = true;
152212
};
153213

214+
215+
//////////////////////////////////////
216+
// identity
217+
//////////////////////////////////////
218+
template <class T>
219+
struct identity
220+
{
221+
typedef T type;
222+
typedef typename add_const_lvalue_reference<T>::type reference;
223+
reference operator()(reference t)
224+
{ return t; }
225+
};
226+
154227
//////////////////////////////////////
155228
// is_class_or_union
156229
//////////////////////////////////////
@@ -241,9 +314,128 @@ class is_convertible
241314

242315
#endif
243316

317+
template<
318+
bool C
319+
, typename F1
320+
, typename F2
321+
>
322+
struct eval_if_c
323+
: if_c<C,F1,F2>::type
324+
{};
325+
326+
template<
327+
typename C
328+
, typename T1
329+
, typename T2
330+
>
331+
struct eval_if
332+
: if_<C,T1,T2>::type
333+
{};
334+
335+
template<class T, class U, class R = void>
336+
struct enable_if_convertible
337+
: enable_if< is_convertible<T, U>, R>
338+
{};
339+
340+
template<class T, class U, class R = void>
341+
struct disable_if_convertible
342+
: disable_if< is_convertible<T, U>, R>
343+
{};
344+
345+
//////////////////////////////////////////////////////////////////////////////
346+
//
347+
// and_
348+
//
349+
//////////////////////////////////////////////////////////////////////////////
350+
template<bool Bool, class B = true_, class C = true_, class D = true_>
351+
struct and_impl
352+
: and_impl<B::value, C, D>
353+
{};
354+
355+
template<>
356+
struct and_impl<true, true_, true_, true_>
357+
{
358+
static const bool value = true;
359+
};
360+
361+
template<class B, class C, class D>
362+
struct and_impl<false, B, C, D>
363+
{
364+
static const bool value = false;
365+
};
366+
367+
template<class A, class B, class C = true_, class D = true_>
368+
struct and_
369+
: and_impl<A::value, B, C, D>
370+
{};
371+
372+
//////////////////////////////////////////////////////////////////////////////
373+
//
374+
// or_
375+
//
376+
//////////////////////////////////////////////////////////////////////////////
377+
template<bool Bool, class B = false_, class C = false_, class D = false_>
378+
struct or_impl
379+
: or_impl<B::value, C, D>
380+
{};
381+
382+
template<>
383+
struct or_impl<false, false_, false_, false_>
384+
{
385+
static const bool value = false;
386+
};
387+
388+
template<class B, class C, class D>
389+
struct or_impl<true, B, C, D>
390+
{
391+
static const bool value = true;
392+
};
393+
394+
template<class A, class B, class C = false_, class D = false_>
395+
struct or_
396+
: or_impl<A::value, B, C, D>
397+
{};
398+
399+
//////////////////////////////////////////////////////////////////////////////
400+
//
401+
// not_
402+
//
403+
//////////////////////////////////////////////////////////////////////////////
404+
template<class T>
405+
struct not_
406+
{
407+
static const bool value = !T::value;
408+
};
409+
410+
//////////////////////////////////////////////////////////////////////////////
411+
//
412+
// enable_if_and / disable_if_and / enable_if_or / disable_if_or
413+
//
414+
//////////////////////////////////////////////////////////////////////////////
415+
416+
template<class R, class A, class B, class C = true_, class D = true_>
417+
struct enable_if_and
418+
: enable_if_c< and_<A, B, C, D>::value, R>
419+
{};
420+
421+
template<class R, class A, class B, class C = true_, class D = true_>
422+
struct disable_if_and
423+
: disable_if_c< and_<A, B, C, D>::value, R>
424+
{};
425+
426+
template<class R, class A, class B, class C = false_, class D = false_>
427+
struct enable_if_or
428+
: enable_if_c< or_<A, B, C, D>::value, R>
429+
{};
430+
431+
template<class R, class A, class B, class C = false_, class D = false_>
432+
struct disable_if_or
433+
: disable_if_c< or_<A, B, C, D>::value, R>
434+
{};
435+
244436
//////////////////////////////////////////////////////////////////////////////
245437
//
246-
// has_move_emulation_enabled_impl
438+
// has_move_emulation_enabled_impl
247439
//
248440
//////////////////////////////////////////////////////////////////////////////
249441
template<class T>

include/boost/move/detail/meta_utils_core.hpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,15 @@ template<typename T1, typename T2, typename T3>
4949
struct if_ : if_c<0 != T1::value, T2, T3>
5050
{};
5151

52-
//enable_if_
52+
//////////////////////////////////////
53+
// enable_if_c
54+
//////////////////////////////////////
5355
template <bool B, class T = void>
5456
struct enable_if_c
5557
{
5658
typedef T type;
5759
};
5860

59-
//////////////////////////////////////
60-
// enable_if_c
61-
//////////////////////////////////////
6261
template <class T>
6362
struct enable_if_c<false, T> {};
6463

@@ -68,6 +67,14 @@ struct enable_if_c<false, T> {};
6867
template <class Cond, class T = void>
6968
struct enable_if : enable_if_c<Cond::value, T> {};
7069

70+
//////////////////////////////////////
71+
// disable_if_c
72+
//////////////////////////////////////
73+
template <bool B, class T = void>
74+
struct disable_if_c
75+
: enable_if_c<!B, T>
76+
{};
77+
7178
//////////////////////////////////////
7279
// disable_if
7380
//////////////////////////////////////
@@ -83,19 +90,14 @@ struct integral_constant
8390
static const T value = v;
8491
typedef T value_type;
8592
typedef integral_constant<T, v> type;
93+
94+
operator T() const { return value; }
95+
T operator()() const { return value; }
8696
};
8797

8898
typedef integral_constant<bool, true > true_type;
8999
typedef integral_constant<bool, false > false_type;
90100

91-
//////////////////////////////////////
92-
// identity
93-
//////////////////////////////////////
94-
template <class T>
95-
struct identity
96-
{
97-
typedef T type;
98-
};
99101

100102
//////////////////////////////////////
101103
// is_same

0 commit comments

Comments
 (0)