source: vendor/nemo/current/NEMOGCM/EXTERNAL/XIOS/extern/boost/include/boost/unordered/detail/move.hpp @ 44

Last change on this file since 44 was 44, checked in by cholod, 12 years ago

Load NEMO_TMP into vendor/nemo/current.

File size: 7.6 KB
Line 
1/*
2    Copyright 2005-2007 Adobe Systems Incorporated
3   
4    Use, modification and distribution are subject to the Boost Software License,
5    Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6    http://www.boost.org/LICENSE_1_0.txt).
7*/
8
9/*************************************************************************************************/
10
11#ifndef BOOST_UNORDERED_DETAIL_MOVE_HEADER
12#define BOOST_UNORDERED_DETAIL_MOVE_HEADER
13
14#include <boost/config.hpp>
15#include <boost/mpl/bool.hpp>
16#include <boost/mpl/and.hpp>
17#include <boost/mpl/or.hpp>
18#include <boost/mpl/not.hpp>
19#include <boost/type_traits/is_convertible.hpp>
20#include <boost/type_traits/is_same.hpp>
21#include <boost/type_traits/is_class.hpp>
22#include <boost/utility/enable_if.hpp>
23#include <boost/detail/workaround.hpp>
24
25/*************************************************************************************************/
26
27#if defined(BOOST_NO_SFINAE)
28#  define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
29#elif defined(__GNUC__) && \
30    (__GNUC__ < 3 || __GNUC__ == 3 && __GNUC_MINOR__ <= 3)
31#  define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
32#elif BOOST_WORKAROUND(BOOST_INTEL, < 900) || \
33    BOOST_WORKAROUND(__EDG_VERSION__, < 304) || \
34    BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x0593))
35#  define BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
36#endif
37
38/*************************************************************************************************/
39
40namespace boost {
41namespace unordered_detail {
42
43/*************************************************************************************************/
44
45namespace move_detail {
46
47/*************************************************************************************************/
48
49#if !defined(BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN)
50
51/*************************************************************************************************/
52
53template <typename T> 
54struct class_has_move_assign { 
55    class type {
56        typedef T& (T::*E)(T t); 
57        typedef char (&no_type)[1]; 
58        typedef char (&yes_type)[2]; 
59        template <E e> struct sfinae { typedef yes_type type; }; 
60        template <class U> 
61        static typename sfinae<&U::operator=>::type test(int); 
62        template <class U> 
63        static no_type test(...); 
64    public: 
65        enum {value = sizeof(test<T>(1)) == sizeof(yes_type)}; 
66    };
67 }; 
68
69/*************************************************************************************************/
70
71template<typename T>
72struct has_move_assign : boost::mpl::and_<boost::is_class<T>, class_has_move_assign<T> > {};
73
74/*************************************************************************************************/
75
76class test_can_convert_anything { };
77
78/*************************************************************************************************/
79
80#endif // BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
81
82/*************************************************************************************************/
83
84/*
85    REVISIT (sparent@adobe.com): This is a work around for Boost 1.34.1 and VC++ 2008 where
86    boost::is_convertible<T, T> fails to compile.
87*/
88
89template <typename T, typename U>
90struct is_convertible : boost::mpl::or_<
91    boost::is_same<T, U>,
92    boost::is_convertible<T, U>
93> { };
94
95/*************************************************************************************************/
96
97} //namespace move_detail
98
99
100/*************************************************************************************************/
101
102/*!
103\ingroup move_related
104\brief move_from is used for move_ctors.
105*/
106
107template <typename T>
108struct move_from
109{
110    explicit move_from(T& x) : source(x) { }
111    T& source;
112private:
113    move_from& operator=(move_from const&);
114};
115
116/*************************************************************************************************/
117
118#if !defined(BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN)
119
120/*************************************************************************************************/
121
122/*!
123\ingroup move_related
124\brief The is_movable trait can be used to identify movable types.
125*/
126template <typename T>
127struct is_movable : boost::mpl::and_<
128                        boost::is_convertible<move_from<T>, T>,
129                        move_detail::has_move_assign<T>,
130                        boost::mpl::not_<boost::is_convertible<move_detail::test_can_convert_anything, T> >
131                    > { };
132
133/*************************************************************************************************/
134
135#else // BOOST_UNORDERED_NO_HAS_MOVE_ASSIGN
136
137// On compilers which don't have adequate SFINAE support, treat most types as unmovable,
138// unless the trait is specialized.
139
140template <typename T>
141struct is_movable : boost::mpl::false_ { };
142
143#endif
144
145/*************************************************************************************************/
146
147#if !defined(BOOST_NO_SFINAE)
148
149/*************************************************************************************************/
150
151/*!
152\ingroup move_related
153\brief copy_sink and move_sink are used to select between overloaded operations according to
154 whether type T is movable and convertible to type U.
155\sa move
156*/
157
158template <typename T,
159          typename U = T,
160          typename R = void*>
161struct copy_sink : boost::enable_if<
162                        boost::mpl::and_<
163                            boost::unordered_detail::move_detail::is_convertible<T, U>,                           
164                            boost::mpl::not_<is_movable<T> >
165                        >,
166                        R
167                    >
168{ };
169
170/*************************************************************************************************/
171
172/*!
173\ingroup move_related
174\brief move_sink and copy_sink are used to select between overloaded operations according to
175 whether type T is movable and convertible to type U.
176 \sa move
177*/
178
179template <typename T,
180          typename U = T,
181          typename R = void*>
182struct move_sink : boost::enable_if<
183                        boost::mpl::and_<
184                            boost::unordered_detail::move_detail::is_convertible<T, U>,                           
185                            is_movable<T>
186                        >,
187                        R
188                    >
189{ };
190
191/*************************************************************************************************/
192
193/*!
194\ingroup move_related
195\brief This version of move is selected when T is_movable . It in turn calls the move
196constructor. This call, with the help of the return value optimization, will cause x to be moved
197instead of copied to its destination. See adobe/test/move/main.cpp for examples.
198
199*/
200template <typename T>
201T move(T& x, typename move_sink<T>::type = 0) { return T(move_from<T>(x)); }
202
203/*************************************************************************************************/
204
205/*!
206\ingroup move_related
207\brief This version of move is selected when T is not movable . The net result will be that
208x gets copied.
209*/
210template <typename T>
211T& move(T& x, typename copy_sink<T>::type = 0) { return x; }
212
213/*************************************************************************************************/
214
215#else // BOOST_NO_SFINAE
216
217// On compilers without SFINAE, define copy_sink to always use the copy function.
218
219template <typename T,
220          typename U = T,
221          typename R = void*>
222struct copy_sink
223{
224    typedef R type;
225};
226
227// Always copy the element unless this is overloaded.
228
229template <typename T>
230T& move(T& x) {
231    return x;
232}
233
234#endif // BOOST_NO_SFINAE
235
236} // namespace unordered_detail
237} // namespace boost
238
239/*************************************************************************************************/
240
241#endif
242
243/*************************************************************************************************/
Note: See TracBrowser for help on using the repository browser.