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