add make_pair, rel_ops, and others...

This commit is contained in:
bolero-MURAKAMI 2012-04-12 23:41:06 +09:00
parent f86d17d0d4
commit 2fa0ad1fe4
6 changed files with 293 additions and 1 deletions

View file

@ -43,6 +43,10 @@
// SPROUT_USE_USER_DEFINED_LITERALS
//
//
// SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS
//
//
// SPROUT_CONFIG_USE_SSCRISK_CEL
//

View file

@ -31,6 +31,12 @@
# define SPROUT_USE_USER_DEFINED_LITERALS 0
#endif // #ifndef SPROUT_CONFIG_DISABLE_USER_DEFINED_LITERALS
#ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS
# define SPROUT_USE_DELEGATING_CONSTRUCTORS 1
#else // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS
# define SPROUT_USE_DELEGATING_CONSTRUCTORS 0
#endif // #ifndef SPROUT_CONFIG_DISABLE_DELEGATING_CONSTRUCTORS
#ifndef SPROUT_CONFIG_USE_SSCRISK_CEL
# define HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT <sprout/functional/functor.hpp>
# define HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT <sprout/algorithm/non_modifying.hpp>

View file

@ -238,6 +238,32 @@ namespace sprout {
: public sprout::unwrap_reference<T>
{};
//
// strip_reference
//
template<typename T>
struct strip_reference {
public:
typedef T type;
};
template<typename T>
struct strip_reference<sprout::reference_wrapper<T> > {
public:
typedef T& type;
};
template<typename T>
struct strip_reference<T const>
: public sprout::strip_reference<T>
{};
template<typename T>
struct strip_reference<T volatile>
: public sprout::strip_reference<T>
{};
template<typename T>
struct strip_reference<T const volatile>
: public sprout::strip_reference<T>
{};
//
// unwrap_ref
//

View file

@ -3,6 +3,7 @@
#include <sprout/config.hpp>
#include <sprout/utility/pair.hpp>
#include <sprout/utility/rel_ops.hpp>
#include <sprout/utility/operation.hpp>
#include <sprout/utility/operation_ext.hpp>

View file

@ -1,7 +1,13 @@
#ifndef SPROUT_UTILITY_PAIR_HPP
#define SPROUT_UTILITY_PAIR_HPP
#include <utility>
#include <type_traits>
#include <sprout/config.hpp>
#include <sprout/index_tuple.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/tuple/tuple.hpp>
#include <sprout/functional/ref.hpp>
namespace sprout {
// Copyright (C) 2011 RiSK (sscrisk)
@ -17,8 +23,20 @@ namespace sprout {
public:
T1 first;
T2 second;
private:
template <typename... Args1, typename... Args2, sprout::index_t... Indexes1, sprout::index_t... Indexes2>
SPROUT_CONSTEXPR pair(
sprout::tuples::tuple<Args1...> first_args,
sprout::tuples::tuple<Args2...> second_args,
sprout::index_tuple<Indexes1...>,
sprout::index_tuple<Indexes2...>
)
: first(sprout::tuples::get<Indexes1>(first_args)...)
, second(sprout::tuples::get<Indexes2>(second_args)...)
{}
public:
SPROUT_CONSTEXPR pair(pair const&) = default;
pair(pair const&) = default;
pair(pair&&) = default;
SPROUT_CONSTEXPR pair()
: first()
, second()
@ -28,11 +46,218 @@ namespace sprout {
, second(y)
{}
template<typename U, typename V>
SPROUT_CONSTEXPR pair(U&& x, V&& y)
: first(sprout::forward<U>(x))
, second(sprout::forward<V>(y))
{}
template<typename U, typename V>
SPROUT_CONSTEXPR pair(sprout::pair<U, V> const& p)
: first(p.first)
, second(p.second)
{}
template<typename U, typename V>
SPROUT_CONSTEXPR pair(sprout::pair<U, V>&& p)
: first(sprout::forward<U>(p.first))
, second(sprout::forward<V>(p.second))
{}
#if SPROUT_USE_DELEGATING_CONSTRUCTORS
template <typename... Args1, typename... Args2>
SPROUT_CONSTEXPR pair(
sprout::tuples::tuple<Args1...> first_args,
sprout::tuples::tuple<Args2...> second_args
)
: pair(
first_args,
second_args,
sprout::index_range<0, sizeof...(Args1)>::make(),
sprout::index_range<0, sizeof...(Args2)>::make()
)
{}
#else // #if SPROUT_USE_DELEGATING_CONSTRUCTORS
template <typename... Args1, typename... Args2>
SPROUT_CONSTEXPR pair(
sprout::tuples::tuple<Args1...> first_args,
sprout::tuples::tuple<Args2...> second_args
);
#endif // #if SPROUT_USE_DELEGATING_CONSTRUCTORS
pair& operator=(pair const& p) = default;
template<typename U, typename V>
pair& operator=(sprout::pair<U, V> const& p) {
first = p.first;
second = p.second;
return *this;
}
pair& operator=(pair&& p) SPROUT_NOEXCEPT_EXPR(
std::is_nothrow_move_assignable<T1>::value && std::is_nothrow_move_assignable<T2>::value
)
{
first = sprout::forward<T1>(p.first);
second = std::forward<T2>(p.second);
return *this;
}
template<typename U, typename V>
pair& operator=(sprout::pair<U, V>&& p) {
first = std::forward<U>(p.first);
second = std::forward<V>(p.second);
return *this;
}
void swap(pair& p) SPROUT_NOEXCEPT_EXPR(
SPROUT_NOEXCEPT_EXPR(swap(first, p.first)) && SPROUT_NOEXCEPT_EXPR(swap(second, p.second))
)
{
using std::swap;
swap(first, p.first);
swap(second, p.second);
}
};
template<class T1, class T2>
inline SPROUT_CONSTEXPR bool operator==(sprout::pair<T1, T2> const& x, sprout::pair<T1, T2> const& y) {
return x.first == y.first && x.second == y.second;
}
template<class T1, class T2>
inline SPROUT_CONSTEXPR bool operator!=(sprout::pair<T1, T2> const& x, sprout::pair<T1, T2> const& y) {
return !(x == y);
}
template<class T1, class T2>
inline SPROUT_CONSTEXPR bool operator<(sprout::pair<T1, T2> const& x, sprout::pair<T1, T2> const& y) {
return x.first < y.first
|| (!(y.first < x.first) && x.second < y.second)
;
}
template<class T1, class T2>
inline SPROUT_CONSTEXPR bool operator>(sprout::pair<T1, T2> const& x, sprout::pair<T1, T2> const& y) {
return y < x;
}
template<class T1, class T2>
inline SPROUT_CONSTEXPR bool operator<=(sprout::pair<T1, T2> const& x, sprout::pair<T1, T2> const& y) {
return !(y < x);
}
template<class T1, class T2>
inline SPROUT_CONSTEXPR bool operator>=(sprout::pair<T1, T2> const& x, sprout::pair<T1, T2> const& y) {
return !(x < y);
}
//
// swap
//
template<class T1, class T2>
inline void swap(pair<T1, T2>& x, pair<T1, T2>& y) SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(x.swap(y))) {
x.swap(y);
}
//
// make_pair
//
template<typename T1, typename T2>
SPROUT_CONSTEXPR sprout::pair<
typename sprout::strip_reference<typename std::decay<T1>::type>::type,
typename sprout::strip_reference<typename std::decay<T2>::type>::type
>
make_pair(T1&& x, T2&& y) {
return sprout::pair<
typename sprout::strip_reference<typename std::decay<T1>::type>::type,
typename sprout::strip_reference<typename std::decay<T2>::type>::type
>(
sprout::forward<T1>(x),
sprout::forward<T2>(y)
);
}
} // namespace sprout
namespace sprout {
namespace tuples {
namespace detail {
template<std::size_t I, typename T>
struct tuple_element_impl;
template<typename T1, typename T2>
struct tuple_element_impl<0, sprout::pair<T1, T2> > {
public:
typedef T1 type;
};
template<typename T1, typename T2>
struct tuple_element_impl<1, sprout::pair<T1, T2> > {
public:
typedef T2 type;
};
} // namespace detail
} // namespace tuples
} // namespace sprout
namespace std {
//
// tuple_size
//
template<typename T1, typename T2>
struct tuple_size<sprout::pair<T1, T2> >
: public std::integral_constant<std::size_t, 2>
{};
//
// tuple_element
//
template<std::size_t I, typename T1, typename T2>
struct tuple_element<I, sprout::pair<T1, T2> >
: public sprout::tuples::detail::tuple_element_impl<I, sprout::pair<T1, T2> >
{};
} // namespace std
namespace sprout {
namespace tuples {
//
// get
//
namespace detail {
template<std::size_t I, typename T>
struct get_impl;
template<typename T1, typename T2>
struct get_impl<0, sprout::pair<T1, T2> > {
public:
T1& operator()(sprout::pair<T1, T2>& t) const {
return t.first;
}
T1 const& operator()(sprout::pair<T1, T2> const& t) const {
return t.first;
}
};
template<typename T1, typename T2>
struct get_impl<1, sprout::pair<T1, T2> > {
public:
public:
T2& operator()(sprout::pair<T1, T2>& t) const {
return t.second;
}
T2 const& operator()(sprout::pair<T1, T2> const& t) const {
return t.second;
}
};
} // namespace detail
template<std::size_t I, typename T1, typename T2>
typename sprout::tuples::tuple_element<I, sprout::pair<T1, T2> >::type& get(
sprout::pair<T1, T2>& t
) SPROUT_NOEXCEPT
{
static_assert(I < 2, "get: index out of range");
return sprout::tuples::detail::get_impl<I, sprout::pair<T1, T2> >()(t);
}
template<std::size_t I, typename T1, typename T2>
SPROUT_CONSTEXPR typename sprout::tuples::tuple_element<I, sprout::pair<T1, T2> >::type const& get(
sprout::pair<T1, T2> const& t
) SPROUT_NOEXCEPT
{
static_assert(I < 2, "get: index out of range");
return sprout::tuples::detail::get_impl<I, sprout::pair<T1, T2> >()(t);
}
template<std::size_t I, typename T1, typename T2>
typename sprout::tuples::tuple_element<I, sprout::pair<T1, T2> >::type&& get(
sprout::pair<T1, T2>&& t
) SPROUT_NOEXCEPT
{
return std::move(sprout::tuples::get<I>(t));
}
} // namespace tuples
using sprout::tuples::get;
} // namespace sprout
#endif // #ifndef SPROUT_UTILITY_PAIR_HPP

View file

@ -0,0 +1,30 @@
#ifndef SPROUT_UTILITY_REL_OPS_HPP
#define SPROUT_UTILITY_REL_OPS_HPP
#include <sprout/config.hpp>
namespace sprout {
namespace rel_ops {
template <typename T>
inline SPROUT_CONSTEXPR bool operator!=(T const& x, T const& y) {
return !(x == y);
}
template <typename T>
inline SPROUT_CONSTEXPR bool operator>(T const& x, T const& y) {
return y < x;
}
template <typename T>
inline SPROUT_CONSTEXPR bool operator<=(T const& x, T const& y) {
return !(y < x);
}
template <typename T>
inline SPROUT_CONSTEXPR bool operator>=(T const& x, T const& y) {
return !(x < y);
}
} // namespace rel_ops
} // namespace sprout
#endif // #ifndef SPROUT_UTILITY_REL_OPS_HPP