diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:38:45 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2016-10-06 10:39:52 +0900 |
commit | 5cde13f21d36c7224b0e13d11c4b49379ae5210d (patch) | |
tree | e8269ac85a4b0f7d416e2565fa4f451b5cb41351 /boost/hana/ext | |
parent | d9ec475d945d3035377a0d89ed42e382d8988891 (diff) | |
download | boost-5cde13f21d36c7224b0e13d11c4b49379ae5210d.tar.gz boost-5cde13f21d36c7224b0e13d11c4b49379ae5210d.tar.bz2 boost-5cde13f21d36c7224b0e13d11c4b49379ae5210d.zip |
Imported Upstream version 1.61.0
Change-Id: I96a1f878d1e6164f01e9aadd5147f38fca448d90
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/hana/ext')
-rw-r--r-- | boost/hana/ext/boost.hpp | 21 | ||||
-rw-r--r-- | boost/hana/ext/boost/fusion.hpp | 22 | ||||
-rw-r--r-- | boost/hana/ext/boost/fusion/deque.hpp | 108 | ||||
-rw-r--r-- | boost/hana/ext/boost/fusion/detail/common.hpp | 79 | ||||
-rw-r--r-- | boost/hana/ext/boost/fusion/list.hpp | 111 | ||||
-rw-r--r-- | boost/hana/ext/boost/fusion/tuple.hpp | 49 | ||||
-rw-r--r-- | boost/hana/ext/boost/fusion/vector.hpp | 110 | ||||
-rw-r--r-- | boost/hana/ext/boost/mpl.hpp | 21 | ||||
-rw-r--r-- | boost/hana/ext/boost/mpl/integral_c.hpp | 81 | ||||
-rw-r--r-- | boost/hana/ext/boost/mpl/list.hpp | 186 | ||||
-rw-r--r-- | boost/hana/ext/boost/mpl/vector.hpp | 185 | ||||
-rw-r--r-- | boost/hana/ext/boost/tuple.hpp | 138 | ||||
-rw-r--r-- | boost/hana/ext/std.hpp | 30 | ||||
-rw-r--r-- | boost/hana/ext/std/array.hpp | 163 | ||||
-rw-r--r-- | boost/hana/ext/std/integer_sequence.hpp | 140 | ||||
-rw-r--r-- | boost/hana/ext/std/integral_constant.hpp | 96 | ||||
-rw-r--r-- | boost/hana/ext/std/pair.hpp | 91 | ||||
-rw-r--r-- | boost/hana/ext/std/ratio.hpp | 164 | ||||
-rw-r--r-- | boost/hana/ext/std/tuple.hpp | 190 | ||||
-rw-r--r-- | boost/hana/ext/std/vector.hpp | 110 |
20 files changed, 2095 insertions, 0 deletions
diff --git a/boost/hana/ext/boost.hpp b/boost/hana/ext/boost.hpp new file mode 100644 index 0000000000..2d735c1469 --- /dev/null +++ b/boost/hana/ext/boost.hpp @@ -0,0 +1,21 @@ +/*! +@file +Includes all the adaptors for external Boost libraries. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_HPP +#define BOOST_HANA_EXT_BOOST_HPP + +//! @ingroup group-ext +//! @defgroup group-ext-boost Other Boost adapters +//! Adapters for miscellaneous heterogeneous containers in Boost. + +#include <boost/hana/ext/boost/fusion.hpp> +#include <boost/hana/ext/boost/mpl.hpp> +#include <boost/hana/ext/boost/tuple.hpp> + +#endif // !BOOST_HANA_EXT_BOOST_HPP diff --git a/boost/hana/ext/boost/fusion.hpp b/boost/hana/ext/boost/fusion.hpp new file mode 100644 index 0000000000..dd80e22b5a --- /dev/null +++ b/boost/hana/ext/boost/fusion.hpp @@ -0,0 +1,22 @@ +/*! +@file +Includes all the adaptors for the Boost.Fusion library. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_FUSION_HPP +#define BOOST_HANA_EXT_BOOST_FUSION_HPP + +//! @ingroup group-ext +//! @defgroup group-ext-fusion Boost.Fusion adapters +//! Adapters for Boost.Fusion containers. + +#include <boost/hana/ext/boost/fusion/deque.hpp> +#include <boost/hana/ext/boost/fusion/list.hpp> +#include <boost/hana/ext/boost/fusion/tuple.hpp> +#include <boost/hana/ext/boost/fusion/vector.hpp> + +#endif // !BOOST_HANA_EXT_BOOST_FUSION_HPP diff --git a/boost/hana/ext/boost/fusion/deque.hpp b/boost/hana/ext/boost/fusion/deque.hpp new file mode 100644 index 0000000000..bdf8c14b84 --- /dev/null +++ b/boost/hana/ext/boost/fusion/deque.hpp @@ -0,0 +1,108 @@ +/*! +@file +Adapts `boost::fusion::deque` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_FUSION_DEQUE_HPP +#define BOOST_HANA_EXT_BOOST_FUSION_DEQUE_HPP + +#include <boost/hana/at.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/ext/boost/fusion/detail/common.hpp> +#include <boost/hana/fwd/core/make.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/length.hpp> + +#include <boost/fusion/container/deque.hpp> +#include <boost/fusion/container/generation/make_deque.hpp> +#include <boost/fusion/support/tag_of.hpp> + +#include <cstddef> +#include <type_traits> +#include <utility> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace boost { namespace fusion { + //! @ingroup group-ext-fusion + //! Adapter for Boost.Fusion deques. + //! + //! + //! Modeled concepts + //! ---------------- + //! A Fusion deque is a model of the `Sequence` concept, and all the + //! concepts it refines. That makes it essentially the same as a Hana + //! tuple, although the complexity of some operations might differ from + //! that of a tuple. + //! + //! @include example/ext/boost/fusion/deque.cpp + template <typename ...T> + struct deque { }; +}} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace boost { namespace fusion { + struct deque_tag; + }}} + + template <typename T> + struct tag_of<T, when< + std::is_same< + typename ::boost::fusion::traits::tag_of<T>::type, + ::boost::fusion::traits::tag_of< + ::boost::fusion::deque<> + >::type + >::value + >> { + using type = ext::boost::fusion::deque_tag; + }; + + namespace detail { + template <> + struct is_fusion_sequence<ext::boost::fusion::deque_tag> { + static constexpr bool value = true; + }; + } + + ////////////////////////////////////////////////////////////////////////// + // Iterable (the rest is in detail/common.hpp) + ////////////////////////////////////////////////////////////////////////// + template <> + struct drop_front_impl<ext::boost::fusion::deque_tag> { + template <std::size_t n, typename Xs, std::size_t ...i> + static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) { + return hana::make<ext::boost::fusion::deque_tag>( + hana::at_c<n + i>(static_cast<Xs&&>(xs))... + ); + } + + template <typename Xs, typename N> + static constexpr auto apply(Xs&& xs, N const&) { + constexpr std::size_t n = N::value; + constexpr std::size_t len = decltype(hana::length(xs))::value; + return drop_front_helper<n>(static_cast<Xs&&>(xs), + std::make_index_sequence<(n < len ? len - n : 0)>{}); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Sequence + ////////////////////////////////////////////////////////////////////////// + template <> + struct make_impl<ext::boost::fusion::deque_tag> { + template <typename ...Xs> + static constexpr auto apply(Xs&& ...xs) { + return ::boost::fusion::make_deque(static_cast<Xs&&>(xs)...); + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_BOOST_FUSION_DEQUE_HPP diff --git a/boost/hana/ext/boost/fusion/detail/common.hpp b/boost/hana/ext/boost/fusion/detail/common.hpp new file mode 100644 index 0000000000..c6ba922be5 --- /dev/null +++ b/boost/hana/ext/boost/fusion/detail/common.hpp @@ -0,0 +1,79 @@ +/*! +@file +Defines common methods for all Boost.Fusion sequences. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_FUSION_DETAIL_COMMON_HPP +#define BOOST_HANA_EXT_BOOST_FUSION_DETAIL_COMMON_HPP + +#include <boost/hana/bool.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/concept/sequence.hpp> +#include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/fwd/length.hpp> +#include <boost/hana/integral_constant.hpp> + +#include <boost/fusion/sequence/intrinsic/at.hpp> +#include <boost/fusion/sequence/intrinsic/empty.hpp> +#include <boost/fusion/sequence/intrinsic/size.hpp> + +#include <cstddef> + + +BOOST_HANA_NAMESPACE_BEGIN + namespace detail { + template <typename T> + struct is_fusion_sequence { + static constexpr bool value = false; + }; + } + + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + template <typename S> + struct at_impl<S, when<detail::is_fusion_sequence<S>::value>> { + template <typename Xs, typename N> + static constexpr decltype(auto) apply(Xs&& xs, N const&) { + constexpr std::size_t n = N::value; + return boost::fusion::at_c<n>(static_cast<Xs&&>(xs)); + } + }; + + template <typename S> + struct is_empty_impl<S, when<detail::is_fusion_sequence<S>::value>> { + template <typename Xs> + static constexpr auto apply(Xs&& xs) { + using Empty = decltype(boost::fusion::empty(xs)); + return hana::bool_c<Empty::value>; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Foldable + ////////////////////////////////////////////////////////////////////////// + template <typename S> + struct length_impl<S, when<detail::is_fusion_sequence<S>::value>> { + template <typename Xs> + static constexpr auto apply(Xs const&) { + using Size = typename boost::fusion::result_of::size<Xs>::type; + return hana::size_c<Size::value>; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Sequence + ////////////////////////////////////////////////////////////////////////// + template <typename S> + struct Sequence<S, when<detail::is_fusion_sequence<S>::value>> { + static constexpr bool value = true; + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_BOOST_FUSION_DETAIL_COMMON_HPP diff --git a/boost/hana/ext/boost/fusion/list.hpp b/boost/hana/ext/boost/fusion/list.hpp new file mode 100644 index 0000000000..0f30f7e7f8 --- /dev/null +++ b/boost/hana/ext/boost/fusion/list.hpp @@ -0,0 +1,111 @@ +/*! +@file +Adapts `boost::fusion::list` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_FUSION_LIST_HPP +#define BOOST_HANA_EXT_BOOST_FUSION_LIST_HPP + +#include <boost/hana/config.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/ext/boost/fusion/detail/common.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/core/make.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/length.hpp> + +#include <boost/fusion/algorithm/transformation/pop_front.hpp> +#include <boost/fusion/container/generation/make_list.hpp> +#include <boost/fusion/container/list.hpp> +#include <boost/fusion/container/list/convert.hpp> +#include <boost/fusion/support/tag_of.hpp> +#include <boost/version.hpp> + +#include <cstddef> +#include <type_traits> +#include <utility> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace boost { namespace fusion { + //! @ingroup group-ext-fusion + //! Adapter for Boost.Fusion lists. + //! + //! + //! Modeled concepts + //! ---------------- + //! A Fusion list is a model of the `Sequence` concept, and all the + //! concepts it refines. That makes it essentially the same as a Hana + //! tuple, although the complexity of some operations might differ from + //! that of a tuple. + //! + //! @include example/ext/boost/fusion/list.cpp + template <typename ...T> + struct list { }; +}} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace boost { namespace fusion { + struct list_tag; + }}} + + template <typename T> + struct tag_of<T, when< + std::is_same< + typename ::boost::fusion::traits::tag_of<T>::type, + ::boost::fusion::traits::tag_of< + ::boost::fusion::list<> + >::type + >::value + >> { + using type = ext::boost::fusion::list_tag; + }; + + namespace detail { + template <> + struct is_fusion_sequence<ext::boost::fusion::list_tag> { + static constexpr bool value = true; + }; + } + + ////////////////////////////////////////////////////////////////////////// + // Iterable (the rest is in detail/common.hpp) + ////////////////////////////////////////////////////////////////////////// + template <> + struct drop_front_impl<ext::boost::fusion::list_tag> { + template <std::size_t n, typename Xs, std::size_t ...i> + static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) { + return hana::make<ext::boost::fusion::list_tag>( + hana::at_c<n + i>(static_cast<Xs&&>(xs))... + ); + } + + template <typename Xs, typename N> + static constexpr auto apply(Xs&& xs, N const&) { + constexpr std::size_t n = N::value; + constexpr std::size_t len = decltype(hana::length(xs))::value; + return drop_front_helper<n>(static_cast<Xs&&>(xs), + std::make_index_sequence<(n < len ? len - n : 0)>{}); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Sequence + ////////////////////////////////////////////////////////////////////////// + template <> + struct make_impl<ext::boost::fusion::list_tag> { + template <typename ...Xs> + static constexpr auto apply(Xs&& ...xs) { + return ::boost::fusion::make_list(static_cast<Xs&&>(xs)...); + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_BOOST_FUSION_LIST_HPP diff --git a/boost/hana/ext/boost/fusion/tuple.hpp b/boost/hana/ext/boost/fusion/tuple.hpp new file mode 100644 index 0000000000..d3e0757911 --- /dev/null +++ b/boost/hana/ext/boost/fusion/tuple.hpp @@ -0,0 +1,49 @@ +/*! +@file +Adapts `boost::fusion::tuple` for use with Hana. + +In the current version of Boost.Fusion, `boost::fusion::tuple` is basically +an alias to `boost::fusion::vector`, so both data types share the same +implementation in Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_FUSION_TUPLE_HPP +#define BOOST_HANA_EXT_BOOST_FUSION_TUPLE_HPP + +#include <boost/hana/config.hpp> +#include <boost/hana/ext/boost/fusion/vector.hpp> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace boost { namespace fusion { + //! @ingroup group-ext-fusion + //! Adapter for Boost.Fusion tuples. + //! + //! + //! Modeled concepts + //! ---------------- + //! A Fusion tuple is a model of the `Sequence` concept, and all the + //! concepts it refines. That makes it essentially the same as a Hana + //! tuple, although the complexity of some operations might differ from + //! that of a tuple. + //! + //! @include example/ext/boost/fusion/tuple.cpp + template <typename ...T> + struct tuple { }; +}} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace boost { namespace fusion { + // In the current version of Boost.Fusion, `boost::fusion::tuple` is + // basically an alias to `boost::fusion::vector`, hence the alias. + using tuple_tag = vector_tag; + }}} +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_BOOST_FUSION_TUPLE_HPP diff --git a/boost/hana/ext/boost/fusion/vector.hpp b/boost/hana/ext/boost/fusion/vector.hpp new file mode 100644 index 0000000000..8cf9bdbe50 --- /dev/null +++ b/boost/hana/ext/boost/fusion/vector.hpp @@ -0,0 +1,110 @@ +/*! +@file +Adapts `boost::fusion::vector` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_FUSION_VECTOR_HPP +#define BOOST_HANA_EXT_BOOST_FUSION_VECTOR_HPP + +#include <boost/hana/config.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/ext/boost/fusion/detail/common.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/core/make.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/length.hpp> + +#include <boost/fusion/algorithm/transformation/pop_front.hpp> +#include <boost/fusion/container/generation/make_vector.hpp> +#include <boost/fusion/container/vector.hpp> +#include <boost/fusion/container/vector/convert.hpp> +#include <boost/fusion/support/tag_of.hpp> + +#include <cstddef> +#include <type_traits> +#include <utility> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace boost { namespace fusion { + //! @ingroup group-ext-fusion + //! Adapter for Boost.Fusion vectors. + //! + //! + //! Modeled concepts + //! ---------------- + //! A Fusion vector is a model of the `Sequence` concept, and all the + //! concepts it refines. That makes it essentially the same as a Hana + //! tuple, although the complexity of some operations might differ from + //! that of a tuple. + //! + //! @include example/ext/boost/fusion/vector.cpp + template <typename ...T> + struct vector { }; +}} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace boost { namespace fusion { + struct vector_tag; + }}} + + template <typename T> + struct tag_of<T, when< + std::is_same< + typename ::boost::fusion::traits::tag_of<T>::type, + ::boost::fusion::traits::tag_of< + ::boost::fusion::vector<> + >::type + >::value + >> { + using type = ext::boost::fusion::vector_tag; + }; + + namespace detail { + template <> + struct is_fusion_sequence<ext::boost::fusion::vector_tag> { + static constexpr bool value = true; + }; + } + + ////////////////////////////////////////////////////////////////////////// + // Iterable (the rest is in detail/common.hpp) + ////////////////////////////////////////////////////////////////////////// + template <> + struct drop_front_impl<ext::boost::fusion::vector_tag> { + template <std::size_t n, typename Xs, std::size_t ...i> + static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) { + return hana::make<ext::boost::fusion::vector_tag>( + hana::at_c<n + i>(static_cast<Xs&&>(xs))... + ); + } + + template <typename Xs, typename N> + static constexpr auto apply(Xs&& xs, N const&) { + constexpr std::size_t n = N::value; + constexpr std::size_t len = decltype(hana::length(xs))::value; + return drop_front_helper<n>(static_cast<Xs&&>(xs), + std::make_index_sequence<(n < len ? len - n : 0)>{}); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Sequence + ////////////////////////////////////////////////////////////////////////// + template <> + struct make_impl<ext::boost::fusion::vector_tag> { + template <typename ...Xs> + static constexpr auto apply(Xs&& ...xs) { + return ::boost::fusion::make_vector(static_cast<Xs&&>(xs)...); + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_BOOST_FUSION_VECTOR_HPP diff --git a/boost/hana/ext/boost/mpl.hpp b/boost/hana/ext/boost/mpl.hpp new file mode 100644 index 0000000000..02bf0e1b0f --- /dev/null +++ b/boost/hana/ext/boost/mpl.hpp @@ -0,0 +1,21 @@ +/*! +@file +Includes all the adaptors for the Boost.MPL library. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_MPL_HPP +#define BOOST_HANA_EXT_BOOST_MPL_HPP + +//! @ingroup group-ext +//! @defgroup group-ext-mpl Boost.MPL adapters +//! Adapters for Boost.MPL containers. + +#include <boost/hana/ext/boost/mpl/integral_c.hpp> +#include <boost/hana/ext/boost/mpl/list.hpp> +#include <boost/hana/ext/boost/mpl/vector.hpp> + +#endif // !BOOST_HANA_EXT_BOOST_MPL_HPP diff --git a/boost/hana/ext/boost/mpl/integral_c.hpp b/boost/hana/ext/boost/mpl/integral_c.hpp new file mode 100644 index 0000000000..ef2cad0239 --- /dev/null +++ b/boost/hana/ext/boost/mpl/integral_c.hpp @@ -0,0 +1,81 @@ +/*! +@file +Adapts Boost.MPL IntegralConstants for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_MPL_INTEGRAL_C_HPP +#define BOOST_HANA_EXT_BOOST_MPL_INTEGRAL_C_HPP + +#include <boost/hana/concept/integral_constant.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/tag_of.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/fwd/core/to.hpp> + +#include <boost/mpl/integral_c.hpp> +#include <boost/mpl/integral_c_tag.hpp> + +#include <type_traits> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace boost { namespace mpl { + //! @ingroup group-ext-mpl + //! Adapter for IntegralConstants from the Boost.MPL. + //! + //! Provided models + //! --------------- + //! 1. `Constant` and `IntegralConstant`\n + //! A Boost.MPL IntegralConstant is a model of the `IntegralConstant` + //! and `Constant` concepts just like `hana::integral_constant`s are. + //! As a consequence, they are also implicitly a model of the concepts + //! provided for all models of `Constant`. + //! @include example/ext/boost/mpl/integral_c/integral_constant.cpp + template <typename T, T v> + struct integral_c { }; +}} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace boost { namespace mpl { + template <typename T> + struct integral_c_tag { using value_type = T; }; + }}} + + template <typename T> + struct tag_of<T, when< + std::is_same< + typename T::tag, + ::boost::mpl::integral_c_tag + >::value + >> { + using type = ext::boost::mpl::integral_c_tag< + typename hana::tag_of<typename T::value_type>::type + >; + }; + + ////////////////////////////////////////////////////////////////////////// + // IntegralConstant/Constant + ////////////////////////////////////////////////////////////////////////// + template <typename T> + struct IntegralConstant<ext::boost::mpl::integral_c_tag<T>> { + static constexpr bool value = true; + }; + + template <typename T, typename C> + struct to_impl<ext::boost::mpl::integral_c_tag<T>, C, + when<hana::IntegralConstant<C>::value> + > : embedding<is_embedded<typename C::value_type, T>::value> { + template <typename N> + static constexpr auto apply(N const&) { + return ::boost::mpl::integral_c<T, N::value>{}; + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_BOOST_MPL_INTEGRAL_C_HPP diff --git a/boost/hana/ext/boost/mpl/list.hpp b/boost/hana/ext/boost/mpl/list.hpp new file mode 100644 index 0000000000..9e569a7d08 --- /dev/null +++ b/boost/hana/ext/boost/mpl/list.hpp @@ -0,0 +1,186 @@ +/*! +@file +Adapts `boost::mpl::list` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_MPL_LIST_HPP +#define BOOST_HANA_EXT_BOOST_MPL_LIST_HPP + +#include <boost/hana/concept/foldable.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/ext/boost/mpl/integral_c.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/core/to.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/equal.hpp> +#include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/fwd/less.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/length.hpp> +#include <boost/hana/type.hpp> +#include <boost/hana/unpack.hpp> + +#include <boost/mpl/at.hpp> +#include <boost/mpl/empty.hpp> +#include <boost/mpl/equal.hpp> +#include <boost/mpl/list.hpp> +#include <boost/mpl/sequence_tag.hpp> +#include <boost/mpl/size.hpp> + +#include <cstddef> +#include <type_traits> +#include <utility> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace boost { namespace mpl { + //! @ingroup group-ext-mpl + //! Adapter for Boost.MPL lists. + //! + //! + //! Modeled concepts + //! ---------------- + //! It is possible for MPL lists to model a couple of concepts. + //! However, because they are only able to hold types, they lack + //! the generality required to model concepts like `Functor`, + //! `Sequence` and other related concepts. + //! + //! 1. `Comparable`\n + //! Two MPL lists are equal if and only if they contain the same + //! number of types, and if all those types are equal. + //! @include example/ext/boost/mpl/list/comparable.cpp + //! + //! 2. `Foldable`\n + //! Folding a MPL list is equivalent to folding it as a `Sequence`. + //! @include example/ext/boost/mpl/list/foldable.cpp + //! + //! 3. `Iterable`\n + //! Iterating over a MPL list is just iterating over each of the + //! types it contains, as if it were a `Sequence`. + //! @include example/ext/boost/mpl/list/iterable.cpp + //! + //! 4. `Searchable`\n + //! A MPL list can be searched as if it were a tuple containing + //! `hana::type`s. + //! @include example/ext/boost/mpl/list/searchable.cpp + //! + //! + //! Conversion from any `Foldable` + //! ------------------------------ + //! A MPL list can be created from any `Foldable`. More precisely, + //! for a `Foldable` `xs` whose linearization is `[x1, ..., xn]`, + //! @code + //! to<ext::boost::mpl::list_tag>(xs) == mpl::list<t1, ..., tn>{} + //! @endcode + //! where `tk` is the type of `xk`, or the type contained in `xk` if + //! `xk` is a `hana::type`. + //! @warning + //! The limitations on the size of `mpl::list`s are inherited by + //! this conversion utility, and hence trying to convert a `Foldable` + //! containing more than [BOOST_MPL_LIMIT_LIST_SIZE][1] elements is + //! an error. + //! @include example/ext/boost/mpl/list/conversion.cpp + //! + //! [1]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/limit-list-size.html + template <typename ...T> + struct list { }; +}} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace boost { namespace mpl { + using list_tag = ::boost::mpl::sequence_tag< ::boost::mpl::list<>>::type; + }}} + + template <typename T> + struct tag_of<T, when< + std::is_same< + typename ::boost::mpl::sequence_tag<T>::type, + ::boost::mpl::sequence_tag< ::boost::mpl::list<>>::type + >::value + >> { + using type = ext::boost::mpl::list_tag; + }; + + ////////////////////////////////////////////////////////////////////////// + // Comparable + ////////////////////////////////////////////////////////////////////////// + template <> + struct equal_impl<ext::boost::mpl::list_tag, ext::boost::mpl::list_tag> { + template <typename Xs, typename Ys> + static constexpr auto apply(Xs const&, Ys const&) { + return typename ::boost::mpl::equal<Xs, Ys>::type{}; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Foldable + ////////////////////////////////////////////////////////////////////////// + template <> + struct length_impl<ext::boost::mpl::list_tag> { + template <typename Xs> + static constexpr auto apply(Xs const&) { + return hana::size_c< ::boost::mpl::size<Xs>::type::value>; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + template <> + struct at_impl<ext::boost::mpl::list_tag> { + template <typename Ts, typename N> + static constexpr auto apply(Ts const&, N const&) { + constexpr std::size_t n = N::value; + using T = typename ::boost::mpl::at_c<Ts, n>::type; + return hana::type_c<T>; + } + }; + + template <> + struct drop_front_impl<ext::boost::mpl::list_tag> { + template <std::size_t n, typename Xs, std::size_t ...i> + static constexpr auto drop_front_helper(Xs const&, std::index_sequence<i...>) { + return boost::mpl::list< + typename boost::mpl::at_c<Xs, n + i>::type... + >{}; + } + + template <typename Xs, typename N> + static constexpr auto apply(Xs const& xs, N const&) { + constexpr std::size_t n = N::value; + constexpr std::size_t len = decltype(hana::length(xs))::value; + return drop_front_helper<n>(xs, + std::make_index_sequence<(n < len ? len - n : 0)>{}); + } + }; + + template <> + struct is_empty_impl<ext::boost::mpl::list_tag> { + template <typename Xs> + static constexpr auto apply(Xs const&) + { return typename ::boost::mpl::empty<Xs>::type{}; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Conversion from a Foldable + ////////////////////////////////////////////////////////////////////////// + template <typename F> + struct to_impl<ext::boost::mpl::list_tag, F, when<hana::Foldable<F>::value>> { + template <typename Xs> + static constexpr decltype(auto) apply(Xs&& xs) { + auto list_type = hana::unpack(static_cast<Xs&&>(xs), + hana::template_<::boost::mpl::list>); + return typename decltype(list_type)::type{}; + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_BOOST_MPL_LIST_HPP diff --git a/boost/hana/ext/boost/mpl/vector.hpp b/boost/hana/ext/boost/mpl/vector.hpp new file mode 100644 index 0000000000..59cac5dd2b --- /dev/null +++ b/boost/hana/ext/boost/mpl/vector.hpp @@ -0,0 +1,185 @@ +/*! +@file +Adapts `boost::mpl::vector` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_MPL_VECTOR_HPP +#define BOOST_HANA_EXT_BOOST_MPL_VECTOR_HPP + +#include <boost/hana/concept/foldable.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/ext/boost/mpl/integral_c.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/core/to.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/equal.hpp> +#include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/fwd/less.hpp> +#include <boost/hana/integral_constant.hpp> +#include <boost/hana/length.hpp> +#include <boost/hana/type.hpp> +#include <boost/hana/unpack.hpp> + +#include <boost/mpl/at.hpp> +#include <boost/mpl/empty.hpp> +#include <boost/mpl/equal.hpp> +#include <boost/mpl/sequence_tag.hpp> +#include <boost/mpl/size.hpp> +#include <boost/mpl/vector.hpp> + +#include <cstddef> +#include <type_traits> +#include <utility> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace boost { namespace mpl { + //! @ingroup group-ext-mpl + //! Adapter for Boost.MPL vectors. + //! + //! + //! Modeled concepts + //! ---------------- + //! It is possible for MPL vectors to model a couple of concepts. + //! However, because they are only able to hold types, they lack + //! the generality required to model concepts like `Functor`, + //! `Sequence` and other related concepts. + //! + //! 1. `Comparable`\n + //! Two MPL vectors are equal if and only if they contain the same + //! number of types, and if all those types are equal. + //! @include example/ext/boost/mpl/vector/comparable.cpp + //! + //! 2. `Foldable`\n + //! Folding a MPL vector is equivalent to folding it as a `Sequence`. + //! @include example/ext/boost/mpl/vector/foldable.cpp + //! + //! 3. `Iterable`\n + //! Iterating over a MPL vector is just iterating over each of the + //! types it contains, as if it were a `Sequence`. + //! @include example/ext/boost/mpl/vector/iterable.cpp + //! + //! 4. `Searchable`\n + //! A MPL vector can be searched as if it were a tuple containing + //! `hana::type`s. + //! @include example/ext/boost/mpl/vector/searchable.cpp + //! + //! + //! Conversion from any `Foldable` + //! ------------------------------ + //! A MPL vector can be created from any `Foldable`. More precisely, + //! for a `Foldable` `xs` whose linearization is `[x1, ..., xn]`, + //! @code + //! to<ext::boost::mpl::vector_tag>(xs) == mpl::vector<t1, ..., tn> + //! @endcode + //! where `tk` is the type of `xk`, or the type contained in `xk` if + //! `xk` is a `hana::type`. + //! @warning + //! The limitations on the size of `mpl::vector`s are inherited by + //! this conversion utility, and hence trying to convert a `Foldable` + //! containing more than [BOOST_MPL_LIMIT_VECTOR_SIZE][1] elements + //! is an error. + //! @include example/ext/boost/mpl/vector/conversion.cpp + //! + //! [1]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/limit-vector-size.html + template <typename ...T> + struct vector { }; +}} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace boost { namespace mpl { + using vector_tag = ::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type; + }}} + + template <typename T> + struct tag_of<T, when< + std::is_same< + typename ::boost::mpl::sequence_tag<T>::type, + ::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type + >::value + >> { + using type = ext::boost::mpl::vector_tag; + }; + + ////////////////////////////////////////////////////////////////////////// + // Comparable + ////////////////////////////////////////////////////////////////////////// + template <> + struct equal_impl<ext::boost::mpl::vector_tag, ext::boost::mpl::vector_tag> { + template <typename Xs, typename Ys> + static constexpr auto apply(Xs const&, Ys const&) { + return typename ::boost::mpl::equal<Xs, Ys>::type{}; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Foldable + ////////////////////////////////////////////////////////////////////////// + template <> + struct length_impl<ext::boost::mpl::vector_tag> { + template <typename Xs> + static constexpr auto apply(Xs const&) { + return hana::size_c< ::boost::mpl::size<Xs>::type::value>; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + template <> + struct at_impl<ext::boost::mpl::vector_tag> { + template <typename Ts, typename N> + static constexpr auto apply(Ts const&, N const&) { + constexpr std::size_t n = N::value; + using T = typename ::boost::mpl::at_c<Ts, n>::type; + return hana::type_c<T>; + } + }; + + template <> + struct drop_front_impl<ext::boost::mpl::vector_tag> { + template <std::size_t n, typename Xs, std::size_t ...i> + static constexpr auto drop_front_helper(Xs const&, std::index_sequence<i...>) { + return boost::mpl::vector< + typename boost::mpl::at_c<Xs, n + i>::type... + >{}; + } + + template <typename Xs, typename N> + static constexpr auto apply(Xs const& xs, N const&) { + constexpr std::size_t n = N::value; + constexpr std::size_t len = decltype(hana::length(xs))::value; + return drop_front_helper<n>(xs, + std::make_index_sequence<(n < len ? len - n : 0)>{}); + } + }; + + template <> + struct is_empty_impl<ext::boost::mpl::vector_tag> { + template <typename xs> + static constexpr auto apply(xs) + { return typename ::boost::mpl::empty<xs>::type{}; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Conversion from a Foldable + ////////////////////////////////////////////////////////////////////////// + template <typename F> + struct to_impl<ext::boost::mpl::vector_tag, F, when<hana::Foldable<F>::value>> { + template <typename Xs> + static constexpr auto apply(Xs const& xs) { + auto vector_type = hana::unpack(xs, hana::template_<boost::mpl::vector>); + return typename decltype(vector_type)::type{}; + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_BOOST_MPL_VECTOR_HPP diff --git a/boost/hana/ext/boost/tuple.hpp b/boost/hana/ext/boost/tuple.hpp new file mode 100644 index 0000000000..dff9a4a952 --- /dev/null +++ b/boost/hana/ext/boost/tuple.hpp @@ -0,0 +1,138 @@ +/*! +@file +Adapts `boost::tuple` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_BOOST_TUPLE_HPP +#define BOOST_HANA_EXT_BOOST_TUPLE_HPP + +#include <boost/hana/bool.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/detail/decay.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/core/make.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/fwd/length.hpp> +#include <boost/hana/integral_constant.hpp> + +#include <boost/tuple/tuple.hpp> + +#include <cstddef> +#include <utility> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace boost { + //! @ingroup group-ext-boost + //! Adapter for `boost::tuple`s. + //! + //! + //! Modeled concepts + //! ---------------- + //! A `boost::tuple` is a model of the `Sequence` concept, and all the + //! concepts it refines. That makes it essentially the same as a Hana + //! tuple, although the complexity of some operations might differ from + //! that of Hana's tuple. + //! + //! @include example/ext/boost/tuple.cpp + template <typename ...T> + struct tuple { }; +} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace boost { struct tuple_tag; }} + + template <typename ...Xs> + struct tag_of<boost::tuple<Xs...>> { + using type = ext::boost::tuple_tag; + }; + + template <typename H, typename T> + struct tag_of<boost::tuples::cons<H, T>> { + using type = ext::boost::tuple_tag; + }; + + template <> + struct tag_of<boost::tuples::null_type> { + using type = ext::boost::tuple_tag; + }; + + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + template <> + struct at_impl<ext::boost::tuple_tag> { + template <typename Xs, typename N> + static constexpr decltype(auto) apply(Xs&& xs, N const&) { + constexpr std::size_t n = N::value; + return static_cast<Xs&&>(xs).template get<n>(); + } + }; + + template <> + struct drop_front_impl<ext::boost::tuple_tag> { + template <std::size_t n, typename Xs, std::size_t ...i> + static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) { + return hana::make<ext::boost::tuple_tag>( + hana::at_c<n + i>(static_cast<Xs&&>(xs))... + ); + } + + template <typename Xs, typename N> + static constexpr auto apply(Xs&& xs, N const&) { + constexpr std::size_t n = N::value; + constexpr std::size_t len = decltype(hana::length(xs))::value; + return drop_front_helper<n>(static_cast<Xs&&>(xs), + std::make_index_sequence<(n < len ? len - n : 0)>{}); + } + }; + + template <> + struct is_empty_impl<ext::boost::tuple_tag> { + static constexpr auto apply(boost::tuples::null_type const&) + { return hana::true_c; } + + template <typename H, typename T> + static constexpr auto apply(boost::tuples::cons<H, T> const&) + { return hana::false_c; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Foldable + ////////////////////////////////////////////////////////////////////////// + template <> + struct length_impl<ext::boost::tuple_tag> { + template <typename Xs> + static constexpr auto apply(Xs const&) { + return hana::size_c<boost::tuples::length<Xs>::value>; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Sequence + ////////////////////////////////////////////////////////////////////////// + template <> + struct Sequence<ext::boost::tuple_tag> { + static constexpr bool value = true; + }; + + template <> + struct make_impl<ext::boost::tuple_tag> { + template <typename ...Xs> + static constexpr auto apply(Xs&& ...xs) { + return boost::tuples::tuple< + typename detail::decay<Xs>::type... + >{static_cast<Xs&&>(xs)...}; + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_BOOST_TUPLE_HPP diff --git a/boost/hana/ext/std.hpp b/boost/hana/ext/std.hpp new file mode 100644 index 0000000000..0d66408dc9 --- /dev/null +++ b/boost/hana/ext/std.hpp @@ -0,0 +1,30 @@ +/*! +@file +Includes all the adaptors for the standard library. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_STD_HPP +#define BOOST_HANA_EXT_STD_HPP + +//! @ingroup group-ext +//! @defgroup group-ext-std Standard library adapters +//! Adapters for components in the standard library. + +#include <boost/hana/config.hpp> + +#ifndef BOOST_HANA_CONFIG_HAS_NO_STD_TUPLE_ADAPTER +# include <boost/hana/ext/std/tuple.hpp> +#endif + +#include <boost/hana/ext/std/array.hpp> +#include <boost/hana/ext/std/integer_sequence.hpp> +#include <boost/hana/ext/std/integral_constant.hpp> +#include <boost/hana/ext/std/pair.hpp> +#include <boost/hana/ext/std/ratio.hpp> +#include <boost/hana/ext/std/vector.hpp> + +#endif // !BOOST_HANA_EXT_STD_HPP diff --git a/boost/hana/ext/std/array.hpp b/boost/hana/ext/std/array.hpp new file mode 100644 index 0000000000..f733624e57 --- /dev/null +++ b/boost/hana/ext/std/array.hpp @@ -0,0 +1,163 @@ +/*! +@file +Adapts `std::array` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_STD_ARRAY_HPP +#define BOOST_HANA_EXT_STD_ARRAY_HPP + +#include <boost/hana/bool.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/detail/algorithm.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/equal.hpp> +#include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/fwd/length.hpp> +#include <boost/hana/fwd/less.hpp> +#include <boost/hana/integral_constant.hpp> + +#include <array> +#include <cstddef> +#include <type_traits> +#include <utility> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace std { + //! @ingroup group-ext-std + //! Adaptation of `std::array` for Hana. + //! + //! + //! + //! Modeled concepts + //! ---------------- + //! 1. `Comparable`\n + //! `std::array`s are compared as per `std::equal`, except that two arrays + //! with different sizes compare unequal instead of triggering an error + //! and the result of the comparison is `constexpr` if both arrays are + //! `constexpr`. + //! @include example/ext/std/array/comparable.cpp + //! + //! 2. `Orderable`\n + //! `std::array`s are ordered with the usual lexicographical ordering, + //! except that two arrays with different size can be ordered instead + //! of triggering an error and the result of the comparison is `constexpr` + //! if both arrays are `constexpr`. + //! @include example/ext/std/array/orderable.cpp + //! + //! 3. `Foldable`\n + //! Folding an array from the left is equivalent to calling + //! `std::accumulate` on it, except it can be `constexpr`. + //! @include example/ext/std/array/foldable.cpp + //! + //! 4. `Iterable`\n + //! Iterating over a `std::array` is equivalent to iterating over it with + //! a normal `for` loop. + //! @include example/ext/std/array/iterable.cpp + template <typename T, std::size_t N> + struct array { }; +} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace std { struct array_tag; }} + + template <typename T, std::size_t N> + struct tag_of<std::array<T, N>> { + using type = ext::std::array_tag; + }; + + ////////////////////////////////////////////////////////////////////////// + // Foldable + ////////////////////////////////////////////////////////////////////////// + template <> + struct length_impl<ext::std::array_tag> { + template <typename Xs> + static constexpr auto apply(Xs const&) { + return hana::size_c<std::tuple_size<Xs>::type::value>; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + template <> + struct at_impl<ext::std::array_tag> { + template <typename Xs, typename N> + static constexpr decltype(auto) apply(Xs&& xs, N const&) { + constexpr std::size_t n = N::value; + return static_cast<Xs&&>(xs)[n]; + } + }; + + template <> + struct drop_front_impl<ext::std::array_tag> { + template <std::size_t n, typename Xs, std::size_t ...i> + static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) { + using T = typename std::remove_reference<Xs>::type::value_type; + return std::array<T, sizeof...(i)>{{static_cast<Xs&&>(xs)[n + i]...}}; + } + + template <typename Xs, typename N> + static constexpr auto apply(Xs&& xs, N const&) { + constexpr std::size_t n = N::value; + constexpr std::size_t len = std::tuple_size< + typename std::remove_cv< + typename std::remove_reference<Xs>::type + >::type + >::value; + return drop_front_helper<n>(static_cast<Xs&&>(xs), + std::make_index_sequence<(n < len ? len - n : 0)>{}); + } + }; + + template <> + struct is_empty_impl<ext::std::array_tag> { + template <typename T, std::size_t N> + static constexpr auto apply(std::array<T, N> const&) { + return hana::bool_c<N == 0>; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Comparable + ////////////////////////////////////////////////////////////////////////// + template <> + struct equal_impl<ext::std::array_tag, ext::std::array_tag> { + template <typename T, std::size_t n, typename U> + static constexpr bool apply(std::array<T, n> const& xs, std::array<U, n> const& ys) + { return detail::equal(&xs[0], &xs[0] + n, &ys[0], &ys[0] + n); } + + template <typename T, typename U> + static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&) + { return hana::true_c; } + + template <typename T, std::size_t n, typename U, std::size_t m> + static constexpr auto apply(std::array<T, n> const&, std::array<U, m> const&) + { return hana::false_c; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Orderable + ////////////////////////////////////////////////////////////////////////// + template <> + struct less_impl<ext::std::array_tag, ext::std::array_tag> { + template <typename T, typename U> + static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&) + { return hana::false_c; } + + template <typename T, std::size_t n, typename U, std::size_t m> + static constexpr auto apply(std::array<T, n> const& xs, std::array<U, m> const& ys) { + return detail::lexicographical_compare(&xs[0], &xs[0] + n, &ys[0], &ys[0] + m); + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_STD_ARRAY_HPP diff --git a/boost/hana/ext/std/integer_sequence.hpp b/boost/hana/ext/std/integer_sequence.hpp new file mode 100644 index 0000000000..27d01e3137 --- /dev/null +++ b/boost/hana/ext/std/integer_sequence.hpp @@ -0,0 +1,140 @@ +/*! +@file +Adapts `std::integer_sequence` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP +#define BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP + +#include <boost/hana/bool.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/detail/fast_and.hpp> +#include <boost/hana/ext/std/integral_constant.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/equal.hpp> +#include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/fwd/unpack.hpp> + +#include <cstddef> +#include <type_traits> +#include <utility> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace std { + //! @ingroup group-ext-std + //! Adaptation of `std::integer_sequence` for Hana. + //! + //! + //! + //! Modeled concepts + //! ---------------- + //! 1. `Comparable`\n + //! Two `std::integer_sequence`s are equal if and only if they have the + //! same number of elements, and if corresponding elements compare equal. + //! The types of the elements held in both `integer_sequence`s may be + //! different, as long as they can be compared. + //! @include example/ext/std/integer_sequence/comparable.cpp + //! + //! 2. `Foldable`\n + //! Folding an `integer_sequence` is equivalent to folding a sequence of + //! `std::integral_constant`s with the corresponding types. + //! @include example/ext/std/integer_sequence/foldable.cpp + //! + //! 3. `Iterable`\n + //! Iterating over an `integer_sequence` is equivalent to iterating over + //! a sequence of the corresponding `std::integral_constant`s. + //! @include example/ext/std/integer_sequence/iterable.cpp + //! + //! 4. `Searchable`\n + //! Searching through an `integer_sequence` is equivalent to searching + //! through the corresponding sequence of `std::integral_constant`s. + //! @include example/ext/std/integer_sequence/searchable.cpp + template <typename T, T ...v> + struct integer_sequence { }; +} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace std { struct integer_sequence_tag; }} + + template <typename T, T ...v> + struct tag_of<std::integer_sequence<T, v...>> { + using type = ext::std::integer_sequence_tag; + }; + + ////////////////////////////////////////////////////////////////////////// + // Comparable + ////////////////////////////////////////////////////////////////////////// + template <> + struct equal_impl<ext::std::integer_sequence_tag, ext::std::integer_sequence_tag> { + template <typename X, X ...xs, typename Y, Y ...ys> + static constexpr hana::bool_<detail::fast_and<(xs == ys)...>::value> + apply(std::integer_sequence<X, xs...> const&, std::integer_sequence<Y, ys...> const&) + { return {}; } + + template <typename Xs, typename Ys> + static constexpr hana::false_ apply(Xs const&, Ys const&, ...) + { return {}; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Foldable + ////////////////////////////////////////////////////////////////////////// + template <> + struct unpack_impl<ext::std::integer_sequence_tag> { + template <typename T, T ...v, typename F> + static constexpr decltype(auto) + apply(std::integer_sequence<T, v...> const&, F&& f) { + return static_cast<F&&>(f)(std::integral_constant<T, v>{}...); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + template <> + struct at_impl<ext::std::integer_sequence_tag> { + template <typename T, T ...v, typename N> + static constexpr auto apply(std::integer_sequence<T, v...> const&, N const&) { + constexpr std::size_t n = N::value; + constexpr T values[] = {v...}; + return std::integral_constant<T, values[n]>{}; + } + }; + + template <> + struct drop_front_impl<ext::std::integer_sequence_tag> { + template <std::size_t n, typename T, T ...t, std::size_t ...i> + static constexpr auto drop_front_helper(std::integer_sequence<T, t...>, + std::index_sequence<i...>) + { + constexpr T ts[sizeof...(t)+1] = {t...}; // avoid 0-sized array + return std::integer_sequence<T, ts[n + i]...>{}; + } + + template <typename T, T ...t, typename N> + static constexpr auto apply(std::integer_sequence<T, t...> ts, N const&) { + constexpr std::size_t n = N::value; + constexpr std::size_t len = sizeof...(t); + return drop_front_helper<n>(ts, + std::make_index_sequence<(n < len ? len - n : 0)>{}); + } + }; + + template <> + struct is_empty_impl<ext::std::integer_sequence_tag> { + template <typename T, T ...xs> + static constexpr auto apply(std::integer_sequence<T, xs...> const&) + { return hana::bool_c<sizeof...(xs) == 0>; } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP diff --git a/boost/hana/ext/std/integral_constant.hpp b/boost/hana/ext/std/integral_constant.hpp new file mode 100644 index 0000000000..28d8f05fb8 --- /dev/null +++ b/boost/hana/ext/std/integral_constant.hpp @@ -0,0 +1,96 @@ +/*! +@file +Adapts `std::integral_constant` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP +#define BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP + +#include <boost/hana/concept/integral_constant.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/fwd/core/to.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/integral_constant.hpp> + +#include <type_traits> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace std { + //! @ingroup group-ext-std + //! Adapter for `std::integral_constant`s. + //! + //! Provided models + //! --------------- + //! 1. `Constant` and `IntegralConstant`\n + //! A `std::integral_constant` is a model of the `IntegralConstant` and + //! `Constant` concepts, just like `hana::integral_constant`s are. As a + //! consequence, they are also implicitly a model of the concepts provided + //! for all models of `Constant`. + //! @include example/ext/std/integral_constant.cpp + template <typename T, T v> + struct integral_constant { }; +} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace std { + template <typename T> + struct integral_constant_tag { using value_type = T; }; + }} + + namespace detail { + template <typename T, T v> + constexpr bool + is_std_integral_constant(std::integral_constant<T, v>*) + { return true; } + + constexpr bool is_std_integral_constant(...) + { return false; } + + + template <typename T, T v> + constexpr bool + is_hana_integral_constant(hana::integral_constant<T, v>*) + { return true; } + + constexpr bool is_hana_integral_constant(...) + { return false; } + } + + template <typename T> + struct tag_of<T, when< + detail::is_std_integral_constant((T*)0) && + !detail::is_hana_integral_constant((T*)0) + >> { + using type = ext::std::integral_constant_tag< + typename hana::tag_of<typename T::value_type>::type + >; + }; + + ////////////////////////////////////////////////////////////////////////// + // Constant/IntegralConstant + ////////////////////////////////////////////////////////////////////////// + template <typename T> + struct IntegralConstant<ext::std::integral_constant_tag<T>> { + static constexpr bool value = true; + }; + + template <typename T, typename C> + struct to_impl<ext::std::integral_constant_tag<T>, C, when< + hana::IntegralConstant<C>::value + >> : embedding<is_embedded<typename C::value_type, T>{}> { + template <typename N> + static constexpr auto apply(N const&) { + return std::integral_constant<T, N::value>{}; + } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP diff --git a/boost/hana/ext/std/pair.hpp b/boost/hana/ext/std/pair.hpp new file mode 100644 index 0000000000..fc60218e85 --- /dev/null +++ b/boost/hana/ext/std/pair.hpp @@ -0,0 +1,91 @@ +/*! +@file +Adapts `std::pair` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_STD_PAIR_HPP +#define BOOST_HANA_EXT_STD_PAIR_HPP + +#include <boost/hana/config.hpp> +#include <boost/hana/fwd/core/make.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/first.hpp> +#include <boost/hana/fwd/second.hpp> + +#include <utility> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace std { + //! @ingroup group-ext-std + //! Adaptation of `std::pair` for Hana. + //! + //! + //! Modeled concepts + //! ---------------- + //! A `std::pair` models exactly the same concepts as a `hana::pair`. + //! Please refer to the documentation of `hana::pair` for details. + //! + //! @include example/ext/std/pair.cpp + template <typename First, typename Second> + struct pair { }; +} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace std { struct pair_tag; }} + + template <typename First, typename Second> + struct tag_of<std::pair<First, Second>> { + using type = ext::std::pair_tag; + }; + + ////////////////////////////////////////////////////////////////////////// + // Product + ////////////////////////////////////////////////////////////////////////// + template <> + struct make_impl<ext::std::pair_tag> { + template <typename X, typename Y> + static constexpr decltype(auto) apply(X&& x, Y&& y) { + return std::make_pair(static_cast<X&&>(x), + static_cast<Y&&>(y)); + } + }; + + template <> + struct first_impl<ext::std::pair_tag> { + template <typename T, typename U> + static constexpr T const& apply(std::pair<T, U> const& p) + { return p.first; } + + template <typename T, typename U> + static constexpr T& apply(std::pair<T, U>& p) + { return p.first; } + + template <typename T, typename U> + static constexpr T&& apply(std::pair<T, U>&& p) + { return static_cast<T&&>(p.first); } + }; + + template <> + struct second_impl<ext::std::pair_tag> { + template <typename T, typename U> + static constexpr U const& apply(std::pair<T, U> const& p) + { return p.second; } + + template <typename T, typename U> + static constexpr U& apply(std::pair<T, U>& p) + { return p.second; } + + template <typename T, typename U> + static constexpr U&& apply(std::pair<T, U>&& p) + { return static_cast<U&&>(p.second); } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_STD_PAIR_HPP diff --git a/boost/hana/ext/std/ratio.hpp b/boost/hana/ext/std/ratio.hpp new file mode 100644 index 0000000000..a301abd1b6 --- /dev/null +++ b/boost/hana/ext/std/ratio.hpp @@ -0,0 +1,164 @@ +/*! +@file +Adapts `std::ratio` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_STD_RATIO_HPP +#define BOOST_HANA_EXT_STD_RATIO_HPP + +#include <boost/hana/bool.hpp> +#include <boost/hana/concept/integral_constant.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/when.hpp> +#include <boost/hana/fwd/core/to.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/div.hpp> +#include <boost/hana/fwd/equal.hpp> +#include <boost/hana/fwd/less.hpp> +#include <boost/hana/fwd/minus.hpp> +#include <boost/hana/fwd/mod.hpp> +#include <boost/hana/fwd/mult.hpp> +#include <boost/hana/fwd/one.hpp> +#include <boost/hana/fwd/plus.hpp> +#include <boost/hana/fwd/zero.hpp> + +#include <cstdint> +#include <ratio> +#include <type_traits> + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace std { + //! @ingroup group-ext-std + //! Adaptation of `std::ratio` for Hana. + //! + //! + //! Modeled concepts + //! ---------------- + //! 1. `Comparable`\n + //! `std::ratio`s are compared for equality using `std::ratio_equal`. + //! @include example/ext/std/ratio/comparable.cpp + //! + //! 2. `Orderable`\n + //! `std::ratio`s are ordered using `std::ratio_less`. + //! @include example/ext/std/ratio/orderable.cpp + //! + //! 3. `Monoid`, `Group`, `Ring`, and `EuclideanRing`\n + //! `std::ratio`s are added, subtracted, multiplied and divided using + //! `std::ratio_add`, `std::ratio_subtract`, `std::ratio_multiply` and + //! `std::ratio_divide`, respectively. Furthermore, the neutral element + //! for the additive operation is `std::ratio<0, 1>{}`, and the neutral + //! element for the multiplicative operation is `std::ratio<1, 1>{}`. + //! @include example/ext/std/ratio/arithmetic.cpp + template <std::intmax_t Num, std::intmax_t Denom> + class ratio { }; +} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace std { struct ratio_tag; }} + + template <std::intmax_t num, std::intmax_t den> + struct tag_of<std::ratio<num, den>> { + using type = ext::std::ratio_tag; + }; + + ////////////////////////////////////////////////////////////////////////// + // Conversion from IntegralConstants + ////////////////////////////////////////////////////////////////////////// + template <typename C> + struct to_impl<ext::std::ratio_tag, C, when< + hana::IntegralConstant<C>::value + >> { + template <typename N> + static constexpr auto apply(N const&) { + return std::ratio<N::value>{}; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Comparable + ////////////////////////////////////////////////////////////////////////// + template <> + struct equal_impl<ext::std::ratio_tag, ext::std::ratio_tag> { + template <typename R1, typename R2> + static constexpr auto apply(R1 const&, R2 const&) + { return hana::bool_c<std::ratio_equal<R1, R2>::value>; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Orderable + ////////////////////////////////////////////////////////////////////////// + template <> + struct less_impl<ext::std::ratio_tag, ext::std::ratio_tag> { + template <typename R1, typename R2> + static constexpr auto apply(R1 const&, R2 const&) + { return hana::bool_c<std::ratio_less<R1, R2>::value>; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Monoid + ////////////////////////////////////////////////////////////////////////// + template <> + struct plus_impl<ext::std::ratio_tag, ext::std::ratio_tag> { + template <typename R1, typename R2> + static constexpr std::ratio_add<R1, R2> apply(R1 const&, R2 const&) + { return {}; } + }; + + template <> + struct zero_impl<ext::std::ratio_tag> { + static constexpr std::ratio<0> apply() + { return {}; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Group + ////////////////////////////////////////////////////////////////////////// + template <> + struct minus_impl<ext::std::ratio_tag, ext::std::ratio_tag> { + template <typename R1, typename R2> + static constexpr std::ratio_subtract<R1, R2> apply(R1 const&, R2 const&) + { return {}; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Ring + ////////////////////////////////////////////////////////////////////////// + template <> + struct mult_impl<ext::std::ratio_tag, ext::std::ratio_tag> { + template <typename R1, typename R2> + static constexpr std::ratio_multiply<R1, R2> apply(R1 const&, R2 const&) + { return {}; } + }; + + template <> + struct one_impl<ext::std::ratio_tag> { + static constexpr std::ratio<1> apply() + { return {}; } + }; + + ////////////////////////////////////////////////////////////////////////// + // EuclideanRing + ////////////////////////////////////////////////////////////////////////// + template <> + struct div_impl<ext::std::ratio_tag, ext::std::ratio_tag> { + template <typename R1, typename R2> + static constexpr std::ratio_divide<R1, R2> apply(R1 const&, R2 const&) + { return {}; } + }; + + template <> + struct mod_impl<ext::std::ratio_tag, ext::std::ratio_tag> { + template <typename R1, typename R2> + static constexpr std::ratio<0> apply(R1 const&, R2 const&) + { return {}; } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_STD_RATIO_HPP diff --git a/boost/hana/ext/std/tuple.hpp b/boost/hana/ext/std/tuple.hpp new file mode 100644 index 0000000000..b2e95d7f30 --- /dev/null +++ b/boost/hana/ext/std/tuple.hpp @@ -0,0 +1,190 @@ +/*! +@file +Adapts `std::tuple` for use with Hana. + +@copyright Louis Dionne 2013-2016 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_STD_TUPLE_HPP +#define BOOST_HANA_EXT_STD_TUPLE_HPP + +#include <boost/hana/bool.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/fwd/at.hpp> +#include <boost/hana/fwd/core/make.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/fwd/drop_front.hpp> +#include <boost/hana/fwd/empty.hpp> +#include <boost/hana/fwd/flatten.hpp> +#include <boost/hana/fwd/front.hpp> +#include <boost/hana/fwd/is_empty.hpp> +#include <boost/hana/fwd/length.hpp> +#include <boost/hana/fwd/lift.hpp> +#include <boost/hana/integral_constant.hpp> + +#include <cstddef> +#include <tuple> +#include <type_traits> +#include <utility> + + +#ifdef BOOST_HANA_CONFIG_HAS_NO_STD_TUPLE_ADAPTER +# error The adapter for std::tuple is not supported with versions of \ + libc++ prior to the one shipped with Clang 3.7 because of a bug \ + in the tuple implementation. +#endif + + +#ifdef BOOST_HANA_DOXYGEN_INVOKED +namespace std { + //! @ingroup group-ext-std + //! Adapter for `std::tuple`s. + //! + //! + //! Modeled concepts + //! ---------------- + //! A `std::tuple` is a model of the `Sequence` concept, and all the + //! concepts it refines. That makes it essentially the same as a Hana + //! tuple, although the complexity of some operations might differ from + //! that of Hana's tuple. + //! + //! @include example/ext/std/tuple.cpp + template <typename ...T> + struct tuple { }; +} +#endif + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace std { struct tuple_tag; }} + + template <typename ...Xs> + struct tag_of<std::tuple<Xs...>> { + using type = ext::std::tuple_tag; + }; + + ////////////////////////////////////////////////////////////////////////// + // make + ////////////////////////////////////////////////////////////////////////// + template <> + struct make_impl<ext::std::tuple_tag> { + template <typename ...Xs> + static constexpr decltype(auto) apply(Xs&& ...xs) { + return std::make_tuple(static_cast<Xs&&>(xs)...); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Applicative + ////////////////////////////////////////////////////////////////////////// + template <> + struct lift_impl<ext::std::tuple_tag> { + template <typename X> + static constexpr auto apply(X&& x) { + return std::tuple<typename std::decay<X>::type>{ + static_cast<X&&>(x)}; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Monad + ////////////////////////////////////////////////////////////////////////// + template <> + struct flatten_impl<ext::std::tuple_tag> { + template <typename Xs, std::size_t ...i> + static constexpr decltype(auto) + flatten_helper(Xs&& xs, std::index_sequence<i...>) { +#if defined(BOOST_HANA_CONFIG_LIBCPP_HAS_BUG_22806) + return std::tuple_cat(std::get<i>(xs)...); +#else + return std::tuple_cat(std::get<i>(static_cast<Xs&&>(xs))...); +#endif + } + + template <typename Xs> + static constexpr decltype(auto) apply(Xs&& xs) { + using Raw = typename std::remove_reference<Xs>::type; + constexpr std::size_t Length = std::tuple_size<Raw>::value; + return flatten_helper(static_cast<Xs&&>(xs), + std::make_index_sequence<Length>{}); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // MonadPlus + ////////////////////////////////////////////////////////////////////////// + template <> + struct empty_impl<ext::std::tuple_tag> { + static constexpr auto apply() + { return std::tuple<>{}; } + }; + + ////////////////////////////////////////////////////////////////////////// + // Iterable + ////////////////////////////////////////////////////////////////////////// + template <> + struct front_impl<ext::std::tuple_tag> { + template <typename Xs> + static constexpr decltype(auto) apply(Xs&& xs) { + return std::get<0>(static_cast<Xs&&>(xs)); + } + }; + + template <> + struct drop_front_impl<ext::std::tuple_tag> { + template <std::size_t n, typename Xs, std::size_t ...i> + static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) { + return std::make_tuple( + hana::at_c<n + i>(static_cast<Xs&&>(xs))... + ); + } + + template <typename Xs, typename N> + static constexpr auto apply(Xs&& xs, N const&) { + using Raw = typename std::remove_reference<Xs>::type; + constexpr std::size_t n = N::value; + constexpr auto len = std::tuple_size<Raw>::value; + return drop_front_helper<n>(static_cast<Xs&&>(xs), + std::make_index_sequence<(n < len ? len - n : 0)>{}); + } + }; + + template <> + struct is_empty_impl<ext::std::tuple_tag> { + template <typename ...Xs> + static constexpr auto apply(std::tuple<Xs...> const&) + { return hana::bool_c<sizeof...(Xs) == 0>; } + }; + + template <> + struct at_impl<ext::std::tuple_tag> { + template <typename Xs, typename N> + static constexpr decltype(auto) apply(Xs&& xs, N const&) { + constexpr std::size_t index = N::value; + return std::get<index>(static_cast<Xs&&>(xs)); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Foldable + ////////////////////////////////////////////////////////////////////////// + template <> + struct length_impl<ext::std::tuple_tag> { + template <typename ...Xs> + static constexpr auto apply(std::tuple<Xs...> const&) { + return hana::size_c<sizeof...(Xs)>; + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Sequence + ////////////////////////////////////////////////////////////////////////// + template <> + struct Sequence<ext::std::tuple_tag> { + static constexpr bool value = true; + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_STD_TUPLE_HPP diff --git a/boost/hana/ext/std/vector.hpp b/boost/hana/ext/std/vector.hpp new file mode 100644 index 0000000000..62b808b2ea --- /dev/null +++ b/boost/hana/ext/std/vector.hpp @@ -0,0 +1,110 @@ +/*! +@file +Adapts `std::vector` for use with Hana. + +@copyright Louis Dionne 2013-2016 +@copyright Gonzalo Brito Gadeschi 2015 +Distributed under the Boost Software License, Version 1.0. +(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) + */ + +#ifndef BOOST_HANA_EXT_STD_VECTOR_HPP +#define BOOST_HANA_EXT_STD_VECTOR_HPP + +#include <boost/hana/config.hpp> +#include <boost/hana/equal.hpp> +#include <boost/hana/fwd/core/tag_of.hpp> +#include <boost/hana/less.hpp> + +#include <algorithm> +#include <iterator> +#include <memory> +#include <type_traits> +#include <utility> +#include <vector> + + +BOOST_HANA_NAMESPACE_BEGIN + namespace ext { namespace std { struct vector_tag; }} + + template <typename T, typename Allocator> + struct tag_of<std::vector<T, Allocator>> { + using type = ext::std::vector_tag; + }; + + ////////////////////////////////////////////////////////////////////////// + // Comparable + ////////////////////////////////////////////////////////////////////////// + template <> + struct equal_impl<ext::std::vector_tag, ext::std::vector_tag> { + template <typename T1, typename A1, typename T2, typename A2> + static bool apply(std::vector<T1, A1> const& v1, + std::vector<T2, A2> const& v2) + { + return std::equal(begin(v1), end(v1), + begin(v2), end(v2), + hana::equal); + } + }; + + ////////////////////////////////////////////////////////////////////////// + // Orderable + ////////////////////////////////////////////////////////////////////////// + template <> + struct less_impl<ext::std::vector_tag, ext::std::vector_tag> { + template <typename T1, typename A1, typename T2, typename A2> + static bool apply(std::vector<T1, A1> const& v1, + std::vector<T2, A2> const& v2) + { + return std::lexicographical_compare(begin(v1), end(v1), + begin(v2), end(v2), + hana::less); + } + }; + +#if 0 + ////////////////////////////////////////////////////////////////////////// + // Functor + ////////////////////////////////////////////////////////////////////////// + template <> + struct transform_impl<ext::std::vector_tag> { + template <typename V, typename F> + static auto apply(V&& v, F&& f) { + using U = std::remove_cv_t<std::remove_reference_t< + decltype(f(*v.begin())) + >>; + using Alloc = typename std::remove_reference_t<V>::allocator_type; + using NewAlloc = typename std::allocator_traits<Alloc>:: + template rebind_alloc<U>; + std::vector<U, NewAlloc> result; result.reserve(v.size()); + + std::transform(begin(v), end(v), + std::back_inserter(result), std::forward<F>(f)); + return result; + } + + template <typename T, typename Alloc, typename F> + static auto apply(std::vector<T, Alloc>&& v, F&& f) + -> std::enable_if_t< + std::is_same< + T, + std::remove_cv_t<std::remove_reference_t< + decltype(f(*v.begin())) + >> + >{} + , std::vector<T, Alloc> + > + { + // If we receive a rvalue and the function returns elements of + // the same type, we modify the vector in-place instead of + // returning a new one. + std::transform(std::make_move_iterator(begin(v)), + std::make_move_iterator(end(v)), + begin(v), std::forward<F>(f)); + return std::move(v); + } + }; +#endif +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_EXT_STD_VECTOR_HPP |