mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2024-11-12 21:09:01 +00:00
reimplementation types::tuple_element, types::tuple_size
This commit is contained in:
parent
609f0b6f8a
commit
39bb8e8ada
8 changed files with 350 additions and 196 deletions
|
@ -12,6 +12,9 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/workaround/std/cstddef.hpp>
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
|
#include <sprout/type_traits/integral_constant.hpp>
|
||||||
|
#include <sprout/type_traits/has_type.hpp>
|
||||||
|
#include <sprout/type_traits/has_value.hpp>
|
||||||
#include <sprout/detail/nil_base.hpp>
|
#include <sprout/detail/nil_base.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
|
@ -20,7 +23,18 @@ namespace sprout {
|
||||||
// tuple_element
|
// tuple_element
|
||||||
//
|
//
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<std::size_t I, typename T, bool = (I < std::tuple_size<T>::value)>
|
template<std::size_t I, typename T, bool = sprout::has_value<std::tuple_size<T> >::value>
|
||||||
|
struct valid_tuple_index;
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct valid_tuple_index<I, T, false>
|
||||||
|
: public sprout::false_type
|
||||||
|
{};
|
||||||
|
template<std::size_t I, typename T>
|
||||||
|
struct valid_tuple_index<I, T, true>
|
||||||
|
: public sprout::integral_constant<bool, (I < std::tuple_size<T>::value)>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<std::size_t I, typename T, bool = sprout::has_type<std::tuple_element<I, T> >::value && sprout::tuples::detail::valid_tuple_index<I, T>::value>
|
||||||
struct tuple_element_default;
|
struct tuple_element_default;
|
||||||
template<std::size_t I, typename T>
|
template<std::size_t I, typename T>
|
||||||
struct tuple_element_default<I, T, false>
|
struct tuple_element_default<I, T, false>
|
||||||
|
|
|
@ -12,15 +12,29 @@
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/workaround/std/cstddef.hpp>
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
#include <sprout/type_traits/detail/type_traits_wrapper.hpp>
|
#include <sprout/type_traits/detail/type_traits_wrapper.hpp>
|
||||||
|
#include <sprout/type_traits/has_value.hpp>
|
||||||
|
#include <sprout/detail/nil_base.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace tuples {
|
namespace tuples {
|
||||||
//
|
//
|
||||||
// tuple_size
|
// tuple_size
|
||||||
//
|
//
|
||||||
|
namespace detail {
|
||||||
|
template<typename T, bool = sprout::has_value<std::tuple_size<T> >::value>
|
||||||
|
struct tuple_size_default;
|
||||||
|
template<typename T>
|
||||||
|
struct tuple_size_default<T, false>
|
||||||
|
: public sprout::detail::nil_base
|
||||||
|
{};
|
||||||
|
template<typename T>
|
||||||
|
struct tuple_size_default<T, true>
|
||||||
|
: public sprout::detail::type_traits_wrapper<std::tuple_size<T> >
|
||||||
|
{};
|
||||||
|
} // namespace detail
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct tuple_size
|
struct tuple_size
|
||||||
: public sprout::detail::type_traits_wrapper<std::tuple_size<T> >
|
: public sprout::tuples::detail::tuple_size_default<T>
|
||||||
{};
|
{};
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct tuple_size<T const>
|
struct tuple_size<T const>
|
||||||
|
|
|
@ -12,7 +12,13 @@
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/workaround/std/cstddef.hpp>
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
#include <sprout/type_traits/detail/type_traits_wrapper.hpp>
|
#include <sprout/type_traits/detail/type_traits_wrapper.hpp>
|
||||||
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
|
#include <sprout/type_traits/has_type.hpp>
|
||||||
|
#include <sprout/type_traits/has_value.hpp>
|
||||||
|
#include <sprout/tuple/tuple/tuple_size.hpp>
|
||||||
#include <sprout/tuple/tuple/tuple_element.hpp>
|
#include <sprout/tuple/tuple/tuple_element.hpp>
|
||||||
|
#include <sprout/type/type_tuple_decl.hpp>
|
||||||
|
#include <sprout/detail/nil_base.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace types {
|
namespace types {
|
||||||
|
@ -34,16 +40,83 @@ namespace sprout {
|
||||||
//
|
//
|
||||||
// tuple_size
|
// tuple_size
|
||||||
//
|
//
|
||||||
template<typename T, typename Enable = void>
|
namespace detail {
|
||||||
|
template<typename Tuple>
|
||||||
|
struct tuple_size_impl
|
||||||
|
: public sprout::detail::nil_base
|
||||||
|
{};
|
||||||
|
template<template<typename...> class TupleClass, typename... Ts>
|
||||||
|
struct tuple_size_impl<TupleClass<Ts...> >
|
||||||
|
: public sprout::integral_constant<std::size_t, sizeof...(Ts)>
|
||||||
|
{};
|
||||||
|
template<template<typename VT, VT...> class IntegerSequenceClass, typename T, T... Vs>
|
||||||
|
struct tuple_size_impl<IntegerSequenceClass<T, Vs...> >
|
||||||
|
: public sprout::integral_constant<std::size_t, sizeof...(Vs)>
|
||||||
|
{};
|
||||||
|
template<template<sprout::index_t...> class IndexTupleClass, sprout::index_t... Vs>
|
||||||
|
struct tuple_size_impl<IndexTupleClass<Vs...> >
|
||||||
|
: public sprout::integral_constant<std::size_t, sizeof...(Vs)>
|
||||||
|
{};
|
||||||
|
template<template<sprout::uindex_t...> class UIndexTupleClass, sprout::uindex_t... Vs>
|
||||||
|
struct tuple_size_impl<UIndexTupleClass<Vs...> >
|
||||||
|
: public sprout::integral_constant<std::size_t, sizeof...(Vs)>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename Tuple, bool = sprout::has_value<sprout::tuples::tuple_size<Tuple> >::value>
|
||||||
|
struct tuple_size_default;
|
||||||
|
template<typename Tuple>
|
||||||
|
struct tuple_size_default<Tuple, false>
|
||||||
|
: public sprout::types::detail::tuple_size_impl<Tuple>
|
||||||
|
{};
|
||||||
|
template<typename Tuple>
|
||||||
|
struct tuple_size_default<Tuple, true>
|
||||||
|
: public sprout::tuples::tuple_size<Tuple>
|
||||||
|
{};
|
||||||
|
} // namespace detail
|
||||||
|
template<typename T>
|
||||||
struct tuple_size
|
struct tuple_size
|
||||||
: public sprout::detail::type_traits_wrapper<std::tuple_size<T> >
|
: public sprout::types::detail::tuple_size_default<T>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
//
|
//
|
||||||
// tuple_element
|
// tuple_element
|
||||||
//
|
//
|
||||||
template<std::size_t I, typename T, typename Enable = void>
|
namespace detail {
|
||||||
|
template<std::size_t I, typename Tuple>
|
||||||
|
struct tuple_element_default_impl
|
||||||
|
: public sprout::detail::nil_base
|
||||||
|
{};
|
||||||
|
template<std::size_t I, template<typename...> class TupleClass, typename... Ts>
|
||||||
|
struct tuple_element_default_impl<I, TupleClass<Ts...> >
|
||||||
|
: public std::tuple_element<I, sprout::types::type_tuple<Ts...> >
|
||||||
|
{};
|
||||||
|
template<std::size_t I, template<typename VT, VT...> class IntegerSequenceClass, typename T, T... Vs>
|
||||||
|
struct tuple_element_default_impl<I, IntegerSequenceClass<T, Vs...> >
|
||||||
|
: public std::tuple_element<I, sprout::types::type_tuple<sprout::integral_constant<T, Vs>...> >
|
||||||
|
{};
|
||||||
|
template<std::size_t I, template<sprout::index_t...> class IndexTupleClass, sprout::index_t... Vs>
|
||||||
|
struct tuple_element_default_impl<I, IndexTupleClass<Vs...> >
|
||||||
|
: public std::tuple_element<I, sprout::types::type_tuple<sprout::integral_constant<sprout::index_t, Vs>...> >
|
||||||
|
{};
|
||||||
|
template<std::size_t I, template<sprout::uindex_t...> class UIndexTupleClass, sprout::uindex_t... Vs>
|
||||||
|
struct tuple_element_default_impl<I, UIndexTupleClass<Vs...> >
|
||||||
|
: public std::tuple_element<I, sprout::types::type_tuple<sprout::integral_constant<sprout::uindex_t, Vs>...> >
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<std::size_t I, typename Tuple, bool = sprout::has_type<sprout::tuples::tuple_element<I, Tuple> >::value>
|
||||||
|
struct tuple_element_default;
|
||||||
|
template<std::size_t I, typename Tuple>
|
||||||
|
struct tuple_element_default<I, Tuple, false>
|
||||||
|
: public sprout::types::detail::tuple_element_default_impl<I, Tuple>
|
||||||
|
{};
|
||||||
|
template<std::size_t I, typename Tuple>
|
||||||
|
struct tuple_element_default<I, Tuple, true>
|
||||||
|
: public sprout::tuples::tuple_element<I, Tuple>
|
||||||
|
{};
|
||||||
|
} // namespace detail
|
||||||
|
template<std::size_t I, typename T>
|
||||||
struct tuple_element
|
struct tuple_element
|
||||||
: public sprout::tuples::tuple_element<I, T>
|
: public sprout::types::detail::tuple_element_default<I, T>
|
||||||
{};
|
{};
|
||||||
|
|
||||||
#if SPROUT_USE_TEMPLATE_ALIASES
|
#if SPROUT_USE_TEMPLATE_ALIASES
|
||||||
|
@ -63,4 +136,6 @@ namespace sprout {
|
||||||
} // namespace types
|
} // namespace types
|
||||||
} // namespace sprout
|
} // namespace sprout
|
||||||
|
|
||||||
|
#include <sprout/type/type_tuple.hpp>
|
||||||
|
|
||||||
#endif // #ifndef SPROUT_TYPE_TUPLE_HPP
|
#endif // #ifndef SPROUT_TYPE_TUPLE_HPP
|
||||||
|
|
|
@ -8,19 +8,11 @@
|
||||||
#ifndef SPROUT_TYPE_TYPE_TUPLE_HPP
|
#ifndef SPROUT_TYPE_TYPE_TUPLE_HPP
|
||||||
#define SPROUT_TYPE_TYPE_TUPLE_HPP
|
#define SPROUT_TYPE_TYPE_TUPLE_HPP
|
||||||
|
|
||||||
#include <tuple>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/workaround/std/cstddef.hpp>
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
#include <sprout/index_tuple/index_n.hpp>
|
|
||||||
#include <sprout/index_tuple/make_index_tuple.hpp>
|
|
||||||
#include <sprout/type/tuple.hpp>
|
|
||||||
#include <sprout/type/iterator.hpp>
|
#include <sprout/type/iterator.hpp>
|
||||||
#include <sprout/type/iterator/index_iterator.hpp>
|
#include <sprout/type/iterator/index_iterator.hpp>
|
||||||
#include <sprout/type/rebind_types.hpp>
|
#include <sprout/type/type_tuple_decl.hpp>
|
||||||
#include <sprout/type_traits/identity.hpp>
|
|
||||||
#include <sprout/type_traits/integral_constant.hpp>
|
|
||||||
#include <sprout/detail/nil_base.hpp>
|
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace types {
|
namespace types {
|
||||||
|
@ -38,186 +30,6 @@ namespace sprout {
|
||||||
};
|
};
|
||||||
template<typename... Types>
|
template<typename... Types>
|
||||||
SPROUT_CONSTEXPR_OR_CONST std::size_t sprout::types::type_tuple<Types...>::static_size;
|
SPROUT_CONSTEXPR_OR_CONST std::size_t sprout::types::type_tuple<Types...>::static_size;
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template<typename Tup>
|
|
||||||
struct head_element;
|
|
||||||
template<>
|
|
||||||
struct head_element<sprout::types::type_tuple<> >
|
|
||||||
: public sprout::detail::nil_base
|
|
||||||
{};
|
|
||||||
template<typename Head, typename... Tail>
|
|
||||||
struct head_element<sprout::types::type_tuple<Head, Tail...> >
|
|
||||||
: public sprout::identity<Head>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename Tup>
|
|
||||||
struct tuple_head;
|
|
||||||
template<>
|
|
||||||
struct tuple_head<sprout::types::type_tuple<> >
|
|
||||||
: public sprout::detail::nil_base
|
|
||||||
{};
|
|
||||||
template<typename Head, typename... Tail>
|
|
||||||
struct tuple_head<sprout::types::type_tuple<Head, Tail...> >
|
|
||||||
: public sprout::identity<sprout::types::type_tuple<Head> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename Tup>
|
|
||||||
struct tuple_tail;
|
|
||||||
template<>
|
|
||||||
struct tuple_tail<sprout::types::type_tuple<> >
|
|
||||||
: public sprout::detail::nil_base
|
|
||||||
{};
|
|
||||||
template<typename Head, typename... Tail>
|
|
||||||
struct tuple_tail<sprout::types::type_tuple<Head, Tail...> >
|
|
||||||
: public sprout::identity<sprout::types::type_tuple<Tail...> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<sprout::index_t, typename T = void>
|
|
||||||
struct dummy_index
|
|
||||||
: public sprout::identity<T>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename Tup1, typename Tup2>
|
|
||||||
struct tuple_cat;
|
|
||||||
template<typename... Types1, typename... Types2>
|
|
||||||
struct tuple_cat<sprout::types::type_tuple<Types1...>, sprout::types::type_tuple<Types2...> >
|
|
||||||
: public sprout::identity<sprout::types::type_tuple<Types1..., Types2...> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<typename IndexTuple>
|
|
||||||
struct tuple_drop_helper;
|
|
||||||
template<sprout::index_t... Indexes>
|
|
||||||
struct tuple_drop_helper<sprout::index_tuple<Indexes...> > {
|
|
||||||
template<typename... Types>
|
|
||||||
static sprout::types::type_tuple<typename Types::type...>
|
|
||||||
eval(typename sprout::types::detail::dummy_index<Indexes>::type*..., Types*...);
|
|
||||||
};
|
|
||||||
template<std::size_t I, typename Tup, bool = (I <= sprout::types::tuple_size<Tup>::value)>
|
|
||||||
struct tuple_drop_impl;
|
|
||||||
template<std::size_t I, typename Tup>
|
|
||||||
struct tuple_drop_impl<I, Tup, false>
|
|
||||||
: public sprout::detail::nil_base
|
|
||||||
{};
|
|
||||||
template<std::size_t I, typename... Types>
|
|
||||||
struct tuple_drop_impl<I, sprout::types::type_tuple<Types...>, true>
|
|
||||||
: public sprout::identity<decltype(
|
|
||||||
sprout::types::detail::tuple_drop_helper<typename sprout::index_n<0, I>::type>
|
|
||||||
::eval(static_cast<sprout::identity<Types>*>(0)...)
|
|
||||||
)>::type
|
|
||||||
{};
|
|
||||||
template<std::size_t I, typename Tup>
|
|
||||||
struct tuple_drop
|
|
||||||
: public sprout::types::detail::tuple_drop_impl<I, Tup>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<std::size_t I, typename Tup, bool = (I < sprout::types::tuple_size<Tup>::value)>
|
|
||||||
struct tuple_element_impl;
|
|
||||||
template<std::size_t I, typename Tup>
|
|
||||||
struct tuple_element_impl<I, Tup, false>
|
|
||||||
: public sprout::detail::nil_base
|
|
||||||
{};
|
|
||||||
template<std::size_t I, typename... Types>
|
|
||||||
struct tuple_element_impl<I, sprout::types::type_tuple<Types...>, true>
|
|
||||||
: public sprout::types::detail::head_element<
|
|
||||||
typename sprout::types::detail::tuple_drop<I, sprout::types::type_tuple<Types...> >::type
|
|
||||||
>
|
|
||||||
{};
|
|
||||||
template<std::size_t I, typename Tup>
|
|
||||||
struct tuple_element
|
|
||||||
: public sprout::types::detail::tuple_element_impl<I, Tup>
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<std::size_t I, typename Tup, typename IndexTuple, bool = (I <= sprout::types::tuple_size<Tup>::value)>
|
|
||||||
struct tuple_take_impl;
|
|
||||||
template<std::size_t I, typename Tup, typename IndexTuple>
|
|
||||||
struct tuple_take_impl<I, Tup, IndexTuple, false>
|
|
||||||
: public sprout::detail::nil_base
|
|
||||||
{};
|
|
||||||
template<std::size_t I, typename... Types, sprout::index_t... Indexes>
|
|
||||||
struct tuple_take_impl<I, sprout::types::type_tuple<Types...>, sprout::index_tuple<Indexes...>, true>
|
|
||||||
: public sprout::identity<
|
|
||||||
sprout::types::type_tuple<
|
|
||||||
typename sprout::types::detail::tuple_element<Indexes, sprout::types::type_tuple<Types...> >::type...
|
|
||||||
>
|
|
||||||
>::type
|
|
||||||
{};
|
|
||||||
template<std::size_t I, typename Tup>
|
|
||||||
struct tuple_take;
|
|
||||||
template<std::size_t I, typename... Types>
|
|
||||||
struct tuple_take<I, sprout::types::type_tuple<Types...> >
|
|
||||||
: public sprout::types::detail::tuple_take_impl<I, sprout::types::type_tuple<Types...>, typename sprout::make_index_tuple<I>::type>
|
|
||||||
{};
|
|
||||||
} // namespace detail
|
|
||||||
} // namespace types
|
|
||||||
|
|
||||||
using sprout::types::type_tuple;
|
|
||||||
using sprout::types::rebind_types;
|
|
||||||
} // namespace sprout
|
|
||||||
|
|
||||||
namespace std {
|
|
||||||
#if defined(__clang__)
|
|
||||||
# pragma clang diagnostic push
|
|
||||||
# pragma clang diagnostic ignored "-Wmismatched-tags"
|
|
||||||
#endif
|
|
||||||
//
|
|
||||||
// tuple_size
|
|
||||||
//
|
|
||||||
template<typename... Types>
|
|
||||||
struct tuple_size<sprout::types::type_tuple<Types...> >
|
|
||||||
: public sprout::integral_constant<std::size_t, sizeof...(Types)>
|
|
||||||
{};
|
|
||||||
|
|
||||||
//
|
|
||||||
// tuple_element
|
|
||||||
//
|
|
||||||
template<std::size_t I, typename... Types>
|
|
||||||
struct tuple_element<I, sprout::types::type_tuple<Types...> >
|
|
||||||
: public sprout::types::detail::tuple_element<I, sprout::types::type_tuple<Types...> >
|
|
||||||
{};
|
|
||||||
#if defined(__clang__)
|
|
||||||
# pragma clang diagnostic pop
|
|
||||||
#endif
|
|
||||||
} // namespace std
|
|
||||||
|
|
||||||
namespace sprout {
|
|
||||||
namespace types {
|
|
||||||
//
|
|
||||||
// push_back
|
|
||||||
//
|
|
||||||
template<typename Tuple, typename... Ts>
|
|
||||||
struct push_back;
|
|
||||||
template<typename... Types, typename... Ts>
|
|
||||||
struct push_back<sprout::types::type_tuple<Types...>, Ts...>
|
|
||||||
: public sprout::identity<sprout::types::type_tuple<Types..., Ts...> >
|
|
||||||
{};
|
|
||||||
//
|
|
||||||
// push_front
|
|
||||||
//
|
|
||||||
template<typename Tuple, typename... Ts>
|
|
||||||
struct push_front;
|
|
||||||
template<typename... Types, typename... Ts>
|
|
||||||
struct push_front<sprout::types::type_tuple<Types...>, Ts...>
|
|
||||||
: public sprout::identity<sprout::types::type_tuple<Ts..., Types...> >
|
|
||||||
{};
|
|
||||||
//
|
|
||||||
// pop_back
|
|
||||||
//
|
|
||||||
template<typename Tuple>
|
|
||||||
struct pop_back;
|
|
||||||
template<typename... Types>
|
|
||||||
struct pop_back<sprout::types::type_tuple<Types...> >
|
|
||||||
: public sprout::types::detail::tuple_take<(sizeof...(Types) - 1), sprout::types::type_tuple<Types...> >
|
|
||||||
{};
|
|
||||||
//
|
|
||||||
// pop_front
|
|
||||||
//
|
|
||||||
template<typename Tuple>
|
|
||||||
struct pop_front;
|
|
||||||
template<typename Head, typename... Tail>
|
|
||||||
struct pop_front<sprout::types::type_tuple<Head, Tail...> >
|
|
||||||
: public sprout::identity<sprout::types::type_tuple<Tail...> >
|
|
||||||
{};
|
|
||||||
} // namespace types
|
} // namespace types
|
||||||
} // namespace sprout
|
} // namespace sprout
|
||||||
|
|
||||||
|
|
212
sprout/type/type_tuple_decl.hpp
Normal file
212
sprout/type/type_tuple_decl.hpp
Normal file
|
@ -0,0 +1,212 @@
|
||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2011-2014 Bolero MURAKAMI
|
||||||
|
https://github.com/bolero-MURAKAMI/Sprout
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
=============================================================================*/
|
||||||
|
#ifndef SPROUT_TYPE_TYPE_TUPLE_DECL_HPP
|
||||||
|
#define SPROUT_TYPE_TYPE_TUPLE_DECL_HPP
|
||||||
|
|
||||||
|
#include <tuple>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
|
#include <sprout/index_tuple/index_n.hpp>
|
||||||
|
#include <sprout/index_tuple/make_index_tuple.hpp>
|
||||||
|
#include <sprout/type_traits/identity.hpp>
|
||||||
|
#include <sprout/type_traits/integral_constant.hpp>
|
||||||
|
#include <sprout/type/rebind_types.hpp>
|
||||||
|
#include <sprout/detail/nil_base.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// type_tuple
|
||||||
|
//
|
||||||
|
template<typename... Types>
|
||||||
|
struct type_tuple;
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
template<typename Tup>
|
||||||
|
struct head_element;
|
||||||
|
template<>
|
||||||
|
struct head_element<sprout::types::type_tuple<> >
|
||||||
|
: public sprout::detail::nil_base
|
||||||
|
{};
|
||||||
|
template<typename Head, typename... Tail>
|
||||||
|
struct head_element<sprout::types::type_tuple<Head, Tail...> >
|
||||||
|
: public sprout::identity<Head>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename Tup>
|
||||||
|
struct tuple_head;
|
||||||
|
template<>
|
||||||
|
struct tuple_head<sprout::types::type_tuple<> >
|
||||||
|
: public sprout::detail::nil_base
|
||||||
|
{};
|
||||||
|
template<typename Head, typename... Tail>
|
||||||
|
struct tuple_head<sprout::types::type_tuple<Head, Tail...> >
|
||||||
|
: public sprout::identity<sprout::types::type_tuple<Head> >
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename Tup>
|
||||||
|
struct tuple_tail;
|
||||||
|
template<>
|
||||||
|
struct tuple_tail<sprout::types::type_tuple<> >
|
||||||
|
: public sprout::detail::nil_base
|
||||||
|
{};
|
||||||
|
template<typename Head, typename... Tail>
|
||||||
|
struct tuple_tail<sprout::types::type_tuple<Head, Tail...> >
|
||||||
|
: public sprout::identity<sprout::types::type_tuple<Tail...> >
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<sprout::index_t, typename T = void>
|
||||||
|
struct dummy_index
|
||||||
|
: public sprout::identity<T>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename Tup1, typename Tup2>
|
||||||
|
struct tuple_cat;
|
||||||
|
template<typename... Types1, typename... Types2>
|
||||||
|
struct tuple_cat<sprout::types::type_tuple<Types1...>, sprout::types::type_tuple<Types2...> >
|
||||||
|
: public sprout::identity<sprout::types::type_tuple<Types1..., Types2...> >
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename IndexTuple>
|
||||||
|
struct tuple_drop_helper;
|
||||||
|
template<sprout::index_t... Indexes>
|
||||||
|
struct tuple_drop_helper<sprout::index_tuple<Indexes...> > {
|
||||||
|
template<typename... Types>
|
||||||
|
static sprout::types::type_tuple<typename Types::type...>
|
||||||
|
eval(typename sprout::types::detail::dummy_index<Indexes>::type*..., Types*...);
|
||||||
|
};
|
||||||
|
template<std::size_t I, typename Tup, bool = (I <= std::tuple_size<Tup>::value)>
|
||||||
|
struct tuple_drop_impl;
|
||||||
|
template<std::size_t I, typename Tup>
|
||||||
|
struct tuple_drop_impl<I, Tup, false>
|
||||||
|
: public sprout::detail::nil_base
|
||||||
|
{};
|
||||||
|
template<std::size_t I, typename... Types>
|
||||||
|
struct tuple_drop_impl<I, sprout::types::type_tuple<Types...>, true>
|
||||||
|
: public sprout::identity<decltype(
|
||||||
|
sprout::types::detail::tuple_drop_helper<typename sprout::index_n<0, I>::type>
|
||||||
|
::eval(static_cast<sprout::identity<Types>*>(0)...)
|
||||||
|
)>::type
|
||||||
|
{};
|
||||||
|
template<std::size_t I, typename Tup>
|
||||||
|
struct tuple_drop
|
||||||
|
: public sprout::types::detail::tuple_drop_impl<I, Tup>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<std::size_t I, typename Tup, bool = (I < std::tuple_size<Tup>::value)>
|
||||||
|
struct tuple_element_impl;
|
||||||
|
template<std::size_t I, typename Tup>
|
||||||
|
struct tuple_element_impl<I, Tup, false>
|
||||||
|
: public sprout::detail::nil_base
|
||||||
|
{};
|
||||||
|
template<std::size_t I, typename... Types>
|
||||||
|
struct tuple_element_impl<I, sprout::types::type_tuple<Types...>, true>
|
||||||
|
: public sprout::types::detail::head_element<
|
||||||
|
typename sprout::types::detail::tuple_drop<I, sprout::types::type_tuple<Types...> >::type
|
||||||
|
>
|
||||||
|
{};
|
||||||
|
template<std::size_t I, typename Tup>
|
||||||
|
struct tuple_element
|
||||||
|
: public sprout::types::detail::tuple_element_impl<I, Tup>
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<std::size_t I, typename Tup, typename IndexTuple, bool = (I <= std::tuple_size<Tup>::value)>
|
||||||
|
struct tuple_take_impl;
|
||||||
|
template<std::size_t I, typename Tup, typename IndexTuple>
|
||||||
|
struct tuple_take_impl<I, Tup, IndexTuple, false>
|
||||||
|
: public sprout::detail::nil_base
|
||||||
|
{};
|
||||||
|
template<std::size_t I, typename... Types, sprout::index_t... Indexes>
|
||||||
|
struct tuple_take_impl<I, sprout::types::type_tuple<Types...>, sprout::index_tuple<Indexes...>, true>
|
||||||
|
: public sprout::identity<
|
||||||
|
sprout::types::type_tuple<
|
||||||
|
typename sprout::types::detail::tuple_element<Indexes, sprout::types::type_tuple<Types...> >::type...
|
||||||
|
>
|
||||||
|
>::type
|
||||||
|
{};
|
||||||
|
template<std::size_t I, typename Tup>
|
||||||
|
struct tuple_take;
|
||||||
|
template<std::size_t I, typename... Types>
|
||||||
|
struct tuple_take<I, sprout::types::type_tuple<Types...> >
|
||||||
|
: public sprout::types::detail::tuple_take_impl<I, sprout::types::type_tuple<Types...>, typename sprout::make_index_tuple<I>::type>
|
||||||
|
{};
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace types
|
||||||
|
|
||||||
|
using sprout::types::type_tuple;
|
||||||
|
using sprout::types::rebind_types;
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
#if defined(__clang__)
|
||||||
|
# pragma clang diagnostic push
|
||||||
|
# pragma clang diagnostic ignored "-Wmismatched-tags"
|
||||||
|
#endif
|
||||||
|
//
|
||||||
|
// tuple_size
|
||||||
|
//
|
||||||
|
template<typename... Types>
|
||||||
|
struct tuple_size<sprout::types::type_tuple<Types...> >
|
||||||
|
: public sprout::integral_constant<std::size_t, sizeof...(Types)>
|
||||||
|
{};
|
||||||
|
|
||||||
|
//
|
||||||
|
// tuple_element
|
||||||
|
//
|
||||||
|
template<std::size_t I, typename... Types>
|
||||||
|
struct tuple_element<I, sprout::types::type_tuple<Types...> >
|
||||||
|
: public sprout::types::detail::tuple_element<I, sprout::types::type_tuple<Types...> >
|
||||||
|
{};
|
||||||
|
#if defined(__clang__)
|
||||||
|
# pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace types {
|
||||||
|
//
|
||||||
|
// push_back
|
||||||
|
//
|
||||||
|
template<typename Tuple, typename... Ts>
|
||||||
|
struct push_back;
|
||||||
|
template<typename... Types, typename... Ts>
|
||||||
|
struct push_back<sprout::types::type_tuple<Types...>, Ts...>
|
||||||
|
: public sprout::identity<sprout::types::type_tuple<Types..., Ts...> >
|
||||||
|
{};
|
||||||
|
//
|
||||||
|
// push_front
|
||||||
|
//
|
||||||
|
template<typename Tuple, typename... Ts>
|
||||||
|
struct push_front;
|
||||||
|
template<typename... Types, typename... Ts>
|
||||||
|
struct push_front<sprout::types::type_tuple<Types...>, Ts...>
|
||||||
|
: public sprout::identity<sprout::types::type_tuple<Ts..., Types...> >
|
||||||
|
{};
|
||||||
|
//
|
||||||
|
// pop_back
|
||||||
|
//
|
||||||
|
template<typename Tuple>
|
||||||
|
struct pop_back;
|
||||||
|
template<typename... Types>
|
||||||
|
struct pop_back<sprout::types::type_tuple<Types...> >
|
||||||
|
: public sprout::types::detail::tuple_take<(sizeof...(Types) - 1), sprout::types::type_tuple<Types...> >
|
||||||
|
{};
|
||||||
|
//
|
||||||
|
// pop_front
|
||||||
|
//
|
||||||
|
template<typename Tuple>
|
||||||
|
struct pop_front;
|
||||||
|
template<typename Head, typename... Tail>
|
||||||
|
struct pop_front<sprout::types::type_tuple<Head, Tail...> >
|
||||||
|
: public sprout::identity<sprout::types::type_tuple<Tail...> >
|
||||||
|
{};
|
||||||
|
} // namespace types
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_TYPE_TUPLE_DECL_HPP
|
|
@ -19,6 +19,7 @@
|
||||||
#include <sprout/type_traits/is_char_type.hpp>
|
#include <sprout/type_traits/is_char_type.hpp>
|
||||||
#include <sprout/type_traits/is_c_str.hpp>
|
#include <sprout/type_traits/is_c_str.hpp>
|
||||||
#include <sprout/type_traits/has_type.hpp>
|
#include <sprout/type_traits/has_type.hpp>
|
||||||
|
#include <sprout/type_traits/has_value.hpp>
|
||||||
#include <sprout/type_traits/identity.hpp>
|
#include <sprout/type_traits/identity.hpp>
|
||||||
#include <sprout/type_traits/lvalue_reference.hpp>
|
#include <sprout/type_traits/lvalue_reference.hpp>
|
||||||
#include <sprout/type_traits/const_reference.hpp>
|
#include <sprout/type_traits/const_reference.hpp>
|
||||||
|
|
26
sprout/type_traits/has_value.hpp
Normal file
26
sprout/type_traits/has_value.hpp
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*=============================================================================
|
||||||
|
Copyright (c) 2011-2014 Bolero MURAKAMI
|
||||||
|
https://github.com/bolero-MURAKAMI/Sprout
|
||||||
|
|
||||||
|
Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
=============================================================================*/
|
||||||
|
#ifndef SPROUT_TYPE_TRAITS_HAS_VALUE_HPP
|
||||||
|
#define SPROUT_TYPE_TRAITS_HAS_VALUE_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/type_traits/has_xxx.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
//
|
||||||
|
// has_value
|
||||||
|
//
|
||||||
|
SPROUT_HAS_XXX_VALUE_DEF_LAZY(value);
|
||||||
|
|
||||||
|
#if SPROUT_USE_VARIABLE_TEMPLATES
|
||||||
|
template<typename T>
|
||||||
|
SPROUT_STATIC_CONSTEXPR bool has_value_v = sprout::has_value<T>::value;
|
||||||
|
#endif // #if SPROUT_USE_VARIABLE_TEMPLATES
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_TYPE_TRAITS_HAS_VALUE_HPP
|
|
@ -11,10 +11,10 @@
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/workaround/std/cstddef.hpp>
|
#include <sprout/workaround/std/cstddef.hpp>
|
||||||
#include <sprout/utility/forward.hpp>
|
#include <sprout/utility/forward.hpp>
|
||||||
#include <sprout/type/type_tuple.hpp>
|
|
||||||
#include <sprout/type_traits/integral_constant.hpp>
|
#include <sprout/type_traits/integral_constant.hpp>
|
||||||
#include <sprout/type_traits/identity.hpp>
|
#include <sprout/type_traits/identity.hpp>
|
||||||
#include <sprout/type_traits/enabler_if.hpp>
|
#include <sprout/type_traits/enabler_if.hpp>
|
||||||
|
#include <sprout/type/type_tuple.hpp>
|
||||||
#include <sprout/detail/nil_base.hpp>
|
#include <sprout/detail/nil_base.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
|
|
Loading…
Reference in a new issue