blob: 47d585dc0f76f68c787d1db349dccc3fe2e656ae [file] [log] [blame]
Jeff Thompsona28eed82013-08-22 16:21:10 -07001//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2009-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_MOVE_TRAITS_HPP
15#define BOOST_MOVE_MOVE_TRAITS_HPP
16
17#include <ndnboost/move/detail/config_begin.hpp>
18#include <ndnboost/type_traits/has_trivial_destructor.hpp>
19#include <ndnboost/move/detail/meta_utils.hpp>
20
21#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
22#include <ndnboost/move/core.hpp>
23#endif
24
25namespace ndnboost {
26
27//! If this trait yields to true
28//! (<i>has_trivial_destructor_after_move &lt;T&gt;::value == true</i>)
29//! means that if T is used as argument of a move construction/assignment,
30//! there is no need to call T's destructor.
31//! This optimization tipically is used to improve containers' performance.
32//!
33//! By default this trait is true if the type has trivial destructor,
34//! every class should specialize this trait if it wants to improve performance
35//! when inserted in containers.
36template <class T>
37struct has_trivial_destructor_after_move
38 : ::ndnboost::has_trivial_destructor<T>
39{};
40
41//! By default this traits returns false. Classes with non-throwing move constructor
42//! and assignment can specialize this trait to obtain some performance improvements.
43template <class T>
44struct has_nothrow_move
45 : public ::ndnboost::move_detail::integral_constant<bool, false>
46{};
47
48namespace move_detail {
49
50// Code from Jeffrey Lee Hellrung, many thanks
51
52#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
53 template< class T> struct forward_type { typedef T type; };
54#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
55 template< class T>
56 struct forward_type
57 { typedef const T &type; };
58
59 template< class T>
60 struct forward_type< ndnboost::rv<T> >
61 { typedef T type; };
62#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
63
64template< class T > struct is_rvalue_reference : ::ndnboost::move_detail::integral_constant<bool, false> { };
65#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
66 template< class T > struct is_rvalue_reference< T&& > : ::ndnboost::move_detail::integral_constant<bool, true> { };
67#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
68 template< class T > struct is_rvalue_reference< ndnboost::rv<T>& >
69 : ::ndnboost::move_detail::integral_constant<bool, true>
70 {};
71
72 template< class T > struct is_rvalue_reference< const ndnboost::rv<T>& >
73 : ::ndnboost::move_detail::integral_constant<bool, true>
74 {};
75#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
76
77#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
78 template< class T > struct add_rvalue_reference { typedef T&& type; };
79#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
80 namespace detail_add_rvalue_reference
81 {
82 template< class T
83 , bool emulation = ::ndnboost::has_move_emulation_enabled<T>::value
84 , bool rv = ::ndnboost::move_detail::is_rv<T>::value >
85 struct add_rvalue_reference_impl { typedef T type; };
86
87 template< class T, bool emulation>
88 struct add_rvalue_reference_impl< T, emulation, true > { typedef T & type; };
89
90 template< class T, bool rv >
91 struct add_rvalue_reference_impl< T, true, rv > { typedef ::ndnboost::rv<T>& type; };
92 } // namespace detail_add_rvalue_reference
93
94 template< class T >
95 struct add_rvalue_reference
96 : detail_add_rvalue_reference::add_rvalue_reference_impl<T>
97 { };
98
99 template< class T >
100 struct add_rvalue_reference<T &>
101 { typedef T & type; };
102
103#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
104
105template< class T > struct remove_rvalue_reference { typedef T type; };
106
107#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
108 template< class T > struct remove_rvalue_reference< T&& > { typedef T type; };
109#else // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
110 template< class T > struct remove_rvalue_reference< rv<T> > { typedef T type; };
111 template< class T > struct remove_rvalue_reference< const rv<T> > { typedef T type; };
112 template< class T > struct remove_rvalue_reference< volatile rv<T> > { typedef T type; };
113 template< class T > struct remove_rvalue_reference< const volatile rv<T> > { typedef T type; };
114 template< class T > struct remove_rvalue_reference< rv<T>& > { typedef T type; };
115 template< class T > struct remove_rvalue_reference< const rv<T>& > { typedef T type; };
116 template< class T > struct remove_rvalue_reference< volatile rv<T>& > { typedef T type; };
117 template< class T > struct remove_rvalue_reference< const volatile rv<T>& >{ typedef T type; };
118#endif // #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
119
120template <typename T>
121typename ndnboost::move_detail::add_rvalue_reference<T>::type declval();
122
123} //move_detail {
124
125// Ideas from Boost.Move review, Jeffrey Lee Hellrung:
126//
127//- TypeTraits metafunctions is_lvalue_reference, add_lvalue_reference, and remove_lvalue_reference ?
128// Perhaps add_reference and remove_reference can be modified so that they behave wrt emulated rvalue
129// references the same as wrt real rvalue references, i.e., add_reference< rv<T>& > -> T& rather than
130// rv<T>& (since T&& & -> T&).
131//
132//- Add'l TypeTraits has_[trivial_]move_{constructor,assign}...?
133//
134//- An as_lvalue(T& x) function, which amounts to an identity operation in C++0x, but strips emulated
135// rvalue references in C++03. This may be necessary to prevent "accidental moves".
136
137
138} //namespace ndnboost {
139
140#include <ndnboost/move/detail/config_end.hpp>
141
142#endif //#ifndef BOOST_MOVE_MOVE_TRAITS_HPP