summaryrefslogtreecommitdiff
path: root/boost/hana/ext
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:38:45 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2016-10-06 10:39:52 +0900
commit5cde13f21d36c7224b0e13d11c4b49379ae5210d (patch)
treee8269ac85a4b0f7d416e2565fa4f451b5cb41351 /boost/hana/ext
parentd9ec475d945d3035377a0d89ed42e382d8988891 (diff)
downloadboost-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.hpp21
-rw-r--r--boost/hana/ext/boost/fusion.hpp22
-rw-r--r--boost/hana/ext/boost/fusion/deque.hpp108
-rw-r--r--boost/hana/ext/boost/fusion/detail/common.hpp79
-rw-r--r--boost/hana/ext/boost/fusion/list.hpp111
-rw-r--r--boost/hana/ext/boost/fusion/tuple.hpp49
-rw-r--r--boost/hana/ext/boost/fusion/vector.hpp110
-rw-r--r--boost/hana/ext/boost/mpl.hpp21
-rw-r--r--boost/hana/ext/boost/mpl/integral_c.hpp81
-rw-r--r--boost/hana/ext/boost/mpl/list.hpp186
-rw-r--r--boost/hana/ext/boost/mpl/vector.hpp185
-rw-r--r--boost/hana/ext/boost/tuple.hpp138
-rw-r--r--boost/hana/ext/std.hpp30
-rw-r--r--boost/hana/ext/std/array.hpp163
-rw-r--r--boost/hana/ext/std/integer_sequence.hpp140
-rw-r--r--boost/hana/ext/std/integral_constant.hpp96
-rw-r--r--boost/hana/ext/std/pair.hpp91
-rw-r--r--boost/hana/ext/std/ratio.hpp164
-rw-r--r--boost/hana/ext/std/tuple.hpp190
-rw-r--r--boost/hana/ext/std/vector.hpp110
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