sprout/utility/move.hpp 追加

tuple に要素数の異なるタプルからの暗黙の変換を追加
This commit is contained in:
bolero-MURAKAMI 2011-11-03 13:15:21 +09:00
parent 40036a4c05
commit e11c2eb867
5 changed files with 74 additions and 16 deletions

View file

@ -6,7 +6,7 @@
#include <type_traits> #include <type_traits>
#include <tuple> #include <tuple>
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/utility/forward.hpp> #include <sprout/utility/operation.hpp>
namespace sprout { namespace sprout {
namespace tuples { namespace tuples {
@ -71,6 +71,24 @@ namespace sprout {
void swap(tuple_impl&) SPROUT_NOEXCEPT {} void swap(tuple_impl&) SPROUT_NOEXCEPT {}
public: public:
tuple_impl() = default; tuple_impl() = default;
template<typename... UTypes>
SPROUT_CONSTEXPR explicit tuple_impl(UTypes&&... args) SPROUT_NOEXCEPT {}
SPROUT_CONSTEXPR tuple_impl(tuple_impl const&) = default;
SPROUT_CONSTEXPR tuple_impl(tuple_impl&&) = default;
template<typename... UTypes>
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index, UTypes...> const& t) SPROUT_NOEXCEPT {}
template<typename... UTypes>
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index, UTypes...>&& t) SPROUT_NOEXCEPT {}
tuple_impl& operator=(tuple_impl const&) = default;
tuple_impl& operator=(tuple_impl&& t) = default;
template<typename... UTypes>
tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index, UTypes...> const&) SPROUT_NOEXCEPT {
return *this;
}
template<typename... UTypes>
tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index, UTypes...>&&) SPROUT_NOEXCEPT {
return *this;
}
}; };
template<std::size_t Index, typename Head, typename... Tail> template<std::size_t Index, typename Head, typename... Tail>
class tuple_impl<Index, Head, Tail...> class tuple_impl<Index, Head, Tail...>
@ -87,7 +105,7 @@ namespace sprout {
static SPROUT_CONSTEXPR Head& head(tuple_impl& t) SPROUT_NOEXCEPT { static SPROUT_CONSTEXPR Head& head(tuple_impl& t) SPROUT_NOEXCEPT {
return base_type::head(t); return base_type::head(t);
} }
static SPROUT_CONSTEXPR const Head& head(tuple_impl const& t) SPROUT_NOEXCEPT { static SPROUT_CONSTEXPR Head const& head(tuple_impl const& t) SPROUT_NOEXCEPT {
return base_type::head(t); return base_type::head(t);
} }
static SPROUT_CONSTEXPR inherited_type& tail(tuple_impl& t) SPROUT_NOEXCEPT { static SPROUT_CONSTEXPR inherited_type& tail(tuple_impl& t) SPROUT_NOEXCEPT {
@ -115,7 +133,7 @@ namespace sprout {
: inherited_type(tail...) : inherited_type(tail...)
, base_type(h) , base_type(h)
{} {}
template<typename UHead, typename... UTail, typename = typename std::enable_if<sizeof...(Tail) == sizeof...(UTail)>::type> template<typename UHead, typename... UTail>
SPROUT_CONSTEXPR explicit tuple_impl(UHead&& h, UTail&&... tail) SPROUT_CONSTEXPR explicit tuple_impl(UHead&& h, UTail&&... tail)
: inherited_type(sprout::forward<UTail>(tail)...) : inherited_type(sprout::forward<UTail>(tail)...)
, base_type(sprout::forward<UHead>(h)) , base_type(sprout::forward<UHead>(h))
@ -123,7 +141,7 @@ namespace sprout {
SPROUT_CONSTEXPR tuple_impl(tuple_impl const&) = default; SPROUT_CONSTEXPR tuple_impl(tuple_impl const&) = default;
SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t) SPROUT_CONSTEXPR tuple_impl(tuple_impl&& t)
SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_constructible<Head>::value && std::is_nothrow_move_constructible<inherited_type>::value) SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_constructible<Head>::value && std::is_nothrow_move_constructible<inherited_type>::value)
: inherited_type(std::move(tail(t))) : inherited_type(sprout::move(tail(t)))
, base_type(sprout::forward<Head>(head(t))) , base_type(sprout::forward<Head>(head(t)))
{} {}
template<typename... UTypes> template<typename... UTypes>
@ -133,9 +151,17 @@ namespace sprout {
{} {}
template<typename UHead, typename... UTail> template<typename UHead, typename... UTail>
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index, UHead, UTail...>&& t) SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index, UHead, UTail...>&& t)
: inherited_type(std::move(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::tail(t))) : inherited_type(sprout::move(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::tail(t)))
, base_type(sprout::forward<UHead>(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::head(t))) , base_type(sprout::forward<UHead>(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::head(t)))
{} {}
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index> const& t)
: inherited_type()
, base_type()
{}
SPROUT_CONSTEXPR tuple_impl(tuple_impl<Index>&& t)
: inherited_type()
, base_type()
{}
tuple_impl& operator=(tuple_impl const& t) { tuple_impl& operator=(tuple_impl const& t) {
head(*this) = head(t); head(*this) = head(t);
tail(*this) = tail(t); tail(*this) = tail(t);
@ -145,7 +171,7 @@ namespace sprout {
SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable<Head>::value && std::is_nothrow_move_assignable<inherited_type>::value) SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable<Head>::value && std::is_nothrow_move_assignable<inherited_type>::value)
{ {
head(*this) = sprout::forward<Head>(head(t)); head(*this) = sprout::forward<Head>(head(t));
tail(*this) = std::move(tail(t)); tail(*this) = sprout::move(tail(t));
return *this; return *this;
} }
template<typename... UTypes> template<typename... UTypes>
@ -157,7 +183,15 @@ namespace sprout {
template<typename UHead, typename... UTail> template<typename UHead, typename... UTail>
tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>&& t) { tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>&& t) {
head(*this) = sprout::forward<UHead>(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::head(t)); head(*this) = sprout::forward<UHead>(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::head(t));
tail(*this) = std::move(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::tail(t)); tail(*this) = sprout::move(sprout::tuples::detail::tuple_impl<Index, UHead, UTail...>::tail(t));
return *this;
}
tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index> const& t) {
*this = sprout::move(tuple_impl());
return *this;
}
tuple_impl& operator=(sprout::tuples::detail::tuple_impl<Index>&& t) {
*this = sprout::move(tuple_impl());
return *this; return *this;
} }
}; };
@ -180,17 +214,17 @@ namespace sprout {
SPROUT_CONSTEXPR explicit tuple(Types const&... elements) SPROUT_CONSTEXPR explicit tuple(Types const&... elements)
: inherited_type(elements...) : inherited_type(elements...)
{} {}
template<typename... UTypes, typename = typename std::enable_if<sizeof...(UTypes) == sizeof...(Types)>::type> template<typename... UTypes>
SPROUT_CONSTEXPR explicit tuple(UTypes&&... elements) SPROUT_CONSTEXPR explicit tuple(UTypes&&... elements)
: inherited_type(sprout::forward<UTypes>(elements)...) : inherited_type(sprout::forward<UTypes>(elements)...)
{} {}
SPROUT_CONSTEXPR tuple(tuple const &) = default; SPROUT_CONSTEXPR tuple(tuple const &) = default;
SPROUT_CONSTEXPR tuple(tuple&&) = default; SPROUT_CONSTEXPR tuple(tuple&&) = default;
template<typename... UTypes, typename = typename std::enable_if<sizeof...(UTypes) == sizeof...(Types)>::type> template<typename... UTypes>
SPROUT_CONSTEXPR tuple(sprout::tuples::tuple<UTypes...> const& t) SPROUT_CONSTEXPR tuple(sprout::tuples::tuple<UTypes...> const& t)
: inherited_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...> const&>(t)) : inherited_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...> const&>(t))
{} {}
template<typename... UTypes, typename = typename std::enable_if<sizeof...(UTypes) == sizeof...(Types)>::type> template<typename... UTypes>
SPROUT_CONSTEXPR tuple(sprout::tuples::tuple<UTypes...>&& t) SPROUT_CONSTEXPR tuple(sprout::tuples::tuple<UTypes...>&& t)
: inherited_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...>&&>(t)) : inherited_type(static_cast<sprout::tuples::detail::tuple_impl<0, UTypes...>&&>(t))
{} {}
@ -200,17 +234,17 @@ namespace sprout {
return *this; return *this;
} }
tuple& operator=(tuple&& rhs) SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable<inherited_type>::value) { tuple& operator=(tuple&& rhs) SPROUT_NOEXCEPT_EXPR(std::is_nothrow_move_assignable<inherited_type>::value) {
static_cast<inherited_type&>(*this) = std::move(rhs); static_cast<inherited_type&>(*this) = sprout::move(rhs);
return *this; return *this;
} }
template<typename... UTypes, typename = typename std::enable_if<sizeof...(UTypes) == sizeof...(Types)>::type> template<typename... UTypes>
tuple& operator=(sprout::tuples::tuple<UTypes...> const& rhs) { tuple& operator=(sprout::tuples::tuple<UTypes...> const& rhs) {
static_cast<inherited_type&>(*this) = rhs; static_cast<inherited_type&>(*this) = rhs;
return *this; return *this;
} }
template<typename... UTypes, typename = typename std::enable_if<sizeof...(UTypes) == sizeof...(Types)>::type> template<typename... UTypes>
tuple& operator=(sprout::tuples::tuple<UTypes...>&& rhs) { tuple& operator=(sprout::tuples::tuple<UTypes...>&& rhs) {
static_cast<inherited_type&>(*this) = std::move(rhs); static_cast<inherited_type&>(*this) = sprout::move(rhs);
return *this; return *this;
} }
// tuple swap // tuple swap

View file

@ -2,6 +2,6 @@
#define SPROUT_UTILITY_HPP #define SPROUT_UTILITY_HPP
#include <sprout/config.hpp> #include <sprout/config.hpp>
#include <sprout/utility/forward.hpp> #include <sprout/utility/operation.hpp>
#endif // #ifndef SPROUT_UTILITY_HPP #endif // #ifndef SPROUT_UTILITY_HPP

View file

@ -17,4 +17,3 @@ namespace sprout {
} // namespace sprout } // namespace sprout
#endif // #ifndef SPROUT_UTILITY_FORWARD_HPP #endif // #ifndef SPROUT_UTILITY_FORWARD_HPP

17
sprout/utility/move.hpp Normal file
View file

@ -0,0 +1,17 @@
#ifndef SPROUT_UTILITY_MOVE_HPP
#define SPROUT_UTILITY_MOVE_HPP
#include <type_traits>
#include <sprout/config.hpp>
namespace sprout {
//
// move
//
template<typename T>
SPROUT_CONSTEXPR typename std::remove_reference<T>::type&& move(T&& t) SPROUT_NOEXCEPT {
return static_cast<typename std::remove_reference<T>::type&&>(t);
}
} // namespace sprout
#endif // #ifndef SPROUT_UTILITY_MOVE_HPP

View file

@ -0,0 +1,8 @@
#ifndef SPROUT_UTILITY_OPERATION_HPP
#define SPROUT_UTILITY_OPERATION_HPP
#include <sprout/config.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/utility/move.hpp>
#endif // #ifndef SPROUT_UTILITY_OPERATION_HPP