os/ossrv/ossrv_pub/boost_apis/boost/variant/detail/move.hpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
//-----------------------------------------------------------------------------
sl@0
     2
// boost variant/detail/move.hpp header file
sl@0
     3
// See http://www.boost.org for updates, documentation, and revision history.
sl@0
     4
//-----------------------------------------------------------------------------
sl@0
     5
//
sl@0
     6
//  Copyright (c) 2002-2003 Eric Friedman
sl@0
     7
//  Copyright (c) 2002 by Andrei Alexandrescu
sl@0
     8
//
sl@0
     9
//  Use, modification and distribution are subject to the
sl@0
    10
//  Boost Software License, Version 1.0. (See accompanying file
sl@0
    11
//  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
sl@0
    12
//
sl@0
    13
//  This file derivative of MoJO. Much thanks to Andrei for his initial work.
sl@0
    14
//  See <http://www.cuj.com/experts/2102/alexandr.htm> for information on MOJO.
sl@0
    15
//  Re-issued here under the Boost Software License, with permission of the original
sl@0
    16
//  author (Andrei Alexandrescu).
sl@0
    17
sl@0
    18
sl@0
    19
#ifndef BOOST_VARIANT_DETAIL_MOVE_HPP
sl@0
    20
#define BOOST_VARIANT_DETAIL_MOVE_HPP
sl@0
    21
sl@0
    22
#include <iterator> // for iterator_traits
sl@0
    23
#include <new> // for placement new
sl@0
    24
sl@0
    25
#include "boost/config.hpp"
sl@0
    26
#include "boost/detail/workaround.hpp"
sl@0
    27
#include "boost/mpl/if.hpp"
sl@0
    28
#include "boost/type_traits/is_base_and_derived.hpp"
sl@0
    29
sl@0
    30
namespace boost {
sl@0
    31
namespace detail { namespace variant {
sl@0
    32
sl@0
    33
//////////////////////////////////////////////////////////////////////////
sl@0
    34
// forward declares
sl@0
    35
//
sl@0
    36
// NOTE: Incomplete until (if?) Boost.Move becomes part of Boost.
sl@0
    37
//
sl@0
    38
template <typename Deriving> class moveable;
sl@0
    39
template <typename T>        class move_source;
sl@0
    40
template <typename T>        class move_return;
sl@0
    41
sl@0
    42
namespace detail {
sl@0
    43
sl@0
    44
// (detail) moveable_tag
sl@0
    45
//
sl@0
    46
// Concrete type from which moveable<T> derives.
sl@0
    47
//
sl@0
    48
// TODO: Move into moveable_fwd.hpp and define has_move_constructor.
sl@0
    49
//
sl@0
    50
template <typename Deriving>
sl@0
    51
struct moveable_tag
sl@0
    52
{
sl@0
    53
};
sl@0
    54
sl@0
    55
} // namespace detail
sl@0
    56
sl@0
    57
//////////////////////////////////////////////////////////////////////////
sl@0
    58
// function template move
sl@0
    59
//
sl@0
    60
// Takes a T& and returns, if T derives moveable<T>, a move_source<T> for
sl@0
    61
// the object; else, returns the T&.
sl@0
    62
//
sl@0
    63
sl@0
    64
namespace detail {
sl@0
    65
sl@0
    66
// (detail) class template move_type
sl@0
    67
//
sl@0
    68
// Metafunction that, given moveable T, provides move_source<T>, else T&.
sl@0
    69
//
sl@0
    70
template <typename T>
sl@0
    71
struct move_type
sl@0
    72
{
sl@0
    73
public: // metafunction result
sl@0
    74
sl@0
    75
    typedef typename mpl::if_<
sl@0
    76
          is_base_and_derived<detail::moveable_tag<T>, T>
sl@0
    77
        , move_source<T>
sl@0
    78
        , T&
sl@0
    79
        >::type type;
sl@0
    80
sl@0
    81
};
sl@0
    82
sl@0
    83
} // namespace detail
sl@0
    84
sl@0
    85
template <typename T>
sl@0
    86
inline
sl@0
    87
    typename detail::move_type<T>::type
sl@0
    88
move(T& source)
sl@0
    89
{
sl@0
    90
    typedef typename detail::move_type<T>::type
sl@0
    91
        move_t;
sl@0
    92
sl@0
    93
    return move_t(source);
sl@0
    94
}
sl@0
    95
sl@0
    96
//////////////////////////////////////////////////////////////////////////
sl@0
    97
// class template return_t
sl@0
    98
//
sl@0
    99
// Metafunction that, given moveable T, provides move_return<T>, else T.
sl@0
   100
//
sl@0
   101
template <typename T>
sl@0
   102
struct return_t
sl@0
   103
{
sl@0
   104
public: // metafunction result
sl@0
   105
sl@0
   106
    typedef typename mpl::if_<
sl@0
   107
          is_base_and_derived<moveable<T>, T>
sl@0
   108
        , move_return<T>
sl@0
   109
        , T
sl@0
   110
        >::type type;
sl@0
   111
sl@0
   112
};
sl@0
   113
sl@0
   114
//////////////////////////////////////////////////////////////////////////
sl@0
   115
// function template move_swap
sl@0
   116
//
sl@0
   117
// Swaps using Koenig lookup but falls back to move-swap for primitive
sl@0
   118
// types and on non-conforming compilers.
sl@0
   119
//
sl@0
   120
sl@0
   121
#if   defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)   \
sl@0
   122
 ||   BOOST_WORKAROUND(__GNUC__, BOOST_TESTED_AT(2))
sl@0
   123
sl@0
   124
// [Indicate that move_swap by overload is disabled...]
sl@0
   125
#define BOOST_NO_MOVE_SWAP_BY_OVERLOAD
sl@0
   126
sl@0
   127
// [...and provide straight swap-by-move implementation:]
sl@0
   128
template <typename T>
sl@0
   129
inline void move_swap(T& lhs, T& rhs)
sl@0
   130
{
sl@0
   131
    T tmp( boost::detail::variant::move(lhs) );
sl@0
   132
    lhs = boost::detail::variant::move(rhs);
sl@0
   133
    rhs = boost::detail::variant::move(tmp);
sl@0
   134
}
sl@0
   135
sl@0
   136
#else// !workaround
sl@0
   137
sl@0
   138
namespace detail { namespace move_swap {
sl@0
   139
sl@0
   140
template <typename T>
sl@0
   141
inline void swap(T& lhs, T& rhs)
sl@0
   142
{
sl@0
   143
    T tmp( boost::detail::variant::move(lhs) );
sl@0
   144
    lhs = boost::detail::variant::move(rhs);
sl@0
   145
    rhs = boost::detail::variant::move(tmp);
sl@0
   146
}
sl@0
   147
sl@0
   148
}} // namespace detail::move_swap
sl@0
   149
sl@0
   150
template <typename T>
sl@0
   151
inline void move_swap(T& lhs, T& rhs)
sl@0
   152
{
sl@0
   153
    using detail::move_swap::swap;
sl@0
   154
sl@0
   155
    swap(lhs, rhs);
sl@0
   156
}
sl@0
   157
sl@0
   158
#endif // workaround
sl@0
   159
sl@0
   160
}} // namespace detail::variant
sl@0
   161
} // namespace boost
sl@0
   162
sl@0
   163
#endif // BOOST_VARIANT_DETAIL_MOVE_HPP
sl@0
   164
sl@0
   165
sl@0
   166