summaryrefslogtreecommitdiff
path: root/boost/hana
diff options
context:
space:
mode:
authorDongHun Kwak <dh0128.kwak@samsung.com>2017-09-13 11:05:34 +0900
committerDongHun Kwak <dh0128.kwak@samsung.com>2017-09-13 11:06:28 +0900
commit34bd32e225e2a8a94104489b31c42e5801cc1f4a (patch)
treed021b579a0c190354819974e1eaf0baa54b551f3 /boost/hana
parentf763a99a501650eff2c60288aa6f10ef916d769e (diff)
downloadboost-34bd32e225e2a8a94104489b31c42e5801cc1f4a.tar.gz
boost-34bd32e225e2a8a94104489b31c42e5801cc1f4a.tar.bz2
boost-34bd32e225e2a8a94104489b31c42e5801cc1f4a.zip
Imported Upstream version 1.63.0upstream/1.63.0
Change-Id: Iac85556a04b7e58d63ba636dedb0986e3555714a Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/hana')
-rw-r--r--boost/hana/at.hpp2
-rw-r--r--boost/hana/basic_tuple.hpp5
-rw-r--r--boost/hana/bool.hpp17
-rw-r--r--boost/hana/concept.hpp1
-rw-r--r--boost/hana/concept/applicative.hpp12
-rw-r--r--boost/hana/concept/comonad.hpp14
-rw-r--r--boost/hana/concept/comparable.hpp11
-rw-r--r--boost/hana/concept/constant.hpp10
-rw-r--r--boost/hana/concept/euclidean_ring.hpp14
-rw-r--r--boost/hana/concept/foldable.hpp12
-rw-r--r--boost/hana/concept/functor.hpp14
-rw-r--r--boost/hana/concept/group.hpp13
-rw-r--r--boost/hana/concept/hashable.hpp10
-rw-r--r--boost/hana/concept/integral_constant.hpp15
-rw-r--r--boost/hana/concept/iterable.hpp16
-rw-r--r--boost/hana/concept/logical.hpp14
-rw-r--r--boost/hana/concept/metafunction.hpp15
-rw-r--r--boost/hana/concept/monad.hpp12
-rw-r--r--boost/hana/concept/monad_plus.hpp12
-rw-r--r--boost/hana/concept/monoid.hpp13
-rw-r--r--boost/hana/concept/orderable.hpp11
-rw-r--r--boost/hana/concept/product.hpp12
-rw-r--r--boost/hana/concept/ring.hpp13
-rw-r--r--boost/hana/concept/searchable.hpp12
-rw-r--r--boost/hana/concept/sequence.hpp15
-rw-r--r--boost/hana/concept/struct.hpp10
-rw-r--r--boost/hana/config.hpp6
-rw-r--r--boost/hana/detail/concepts.hpp2
-rw-r--r--boost/hana/detail/integral_constant.hpp245
-rw-r--r--boost/hana/detail/type_at.hpp57
-rw-r--r--boost/hana/drop_front.hpp2
-rw-r--r--boost/hana/equal.hpp16
-rw-r--r--boost/hana/experimental/printable.hpp14
-rw-r--r--boost/hana/experimental/type_name.hpp64
-rw-r--r--boost/hana/experimental/types.hpp32
-rw-r--r--boost/hana/ext/std/array.hpp2
-rw-r--r--boost/hana/ext/std/integral_constant.hpp2
-rw-r--r--boost/hana/fwd/concept/comparable.hpp13
-rw-r--r--boost/hana/fwd/integral_constant.hpp226
-rw-r--r--boost/hana/fwd/map.hpp50
-rw-r--r--boost/hana/fwd/string.hpp33
-rw-r--r--boost/hana/fwd/type.hpp10
-rw-r--r--boost/hana/length.hpp4
-rw-r--r--boost/hana/map.hpp69
-rw-r--r--boost/hana/string.hpp45
-rw-r--r--boost/hana/version.hpp2
46 files changed, 737 insertions, 462 deletions
diff --git a/boost/hana/at.hpp b/boost/hana/at.hpp
index dc208323b1..86cab698c4 100644
--- a/boost/hana/at.hpp
+++ b/boost/hana/at.hpp
@@ -50,7 +50,7 @@ BOOST_HANA_NAMESPACE_BEGIN
template <std::size_t n, typename Xs>
constexpr decltype(auto) at_c(Xs&& xs) {
- return hana::at(static_cast<Xs&&>(xs), hana::size_c<n>);
+ return hana::at(static_cast<Xs&&>(xs), hana::size_t<n>{});
}
BOOST_HANA_NAMESPACE_END
diff --git a/boost/hana/basic_tuple.hpp b/boost/hana/basic_tuple.hpp
index 50af4e33f5..8651e464bf 100644
--- a/boost/hana/basic_tuple.hpp
+++ b/boost/hana/basic_tuple.hpp
@@ -259,8 +259,9 @@ BOOST_HANA_NAMESPACE_BEGIN
template <>
struct is_empty_impl<basic_tuple_tag> {
template <typename ...Xs>
- static constexpr auto apply(basic_tuple<Xs...> const&)
- { return hana::bool_c<sizeof...(Xs) == 0>; }
+ static constexpr hana::bool_<sizeof...(Xs) == 0>
+ apply(basic_tuple<Xs...> const&)
+ { return {}; }
};
//////////////////////////////////////////////////////////////////////////
diff --git a/boost/hana/bool.hpp b/boost/hana/bool.hpp
index e69654dd85..7ba1bfcb6c 100644
--- a/boost/hana/bool.hpp
+++ b/boost/hana/bool.hpp
@@ -192,8 +192,9 @@ BOOST_HANA_NAMESPACE_BEGIN
namespace literals {
template <char ...c>
- constexpr auto operator"" _c()
- { return llong_c<ic_detail::parse<sizeof...(c)>({c...})>; }
+ constexpr auto operator"" _c() {
+ return hana::llong<ic_detail::parse<sizeof...(c)>({c...})>{};
+ }
}
//////////////////////////////////////////////////////////////////////////
@@ -221,8 +222,10 @@ BOOST_HANA_NAMESPACE_BEGIN
template <typename Cond, typename Then, typename Else>
static constexpr decltype(auto)
apply(Cond const&, Then&& t, Else&& e) {
- return eval_if_impl::apply(hana::bool_c<static_cast<bool>(Cond::value)>,
- static_cast<Then&&>(t), static_cast<Else&&>(e));
+ constexpr bool cond = static_cast<bool>(Cond::value);
+ return eval_if_impl::apply(hana::bool_<cond>{},
+ static_cast<Then&&>(t),
+ static_cast<Else&&>(e));
}
template <typename Then, typename Else>
@@ -241,8 +244,10 @@ BOOST_HANA_NAMESPACE_BEGIN
template <typename Cond, typename Then, typename Else>
static constexpr decltype(auto)
apply(Cond const&, Then&& t, Else&& e) {
- return if_impl::apply(hana::bool_c<static_cast<bool>(Cond::value)>,
- static_cast<Then&&>(t), static_cast<Else&&>(e));
+ constexpr bool cond = static_cast<bool>(Cond::value);
+ return if_impl::apply(hana::bool_<cond>{},
+ static_cast<Then&&>(t),
+ static_cast<Else&&>(e));
}
//! @todo We could return `Then` instead of `auto` to sometimes save
diff --git a/boost/hana/concept.hpp b/boost/hana/concept.hpp
index c8decf9925..0ae73d8b7b 100644
--- a/boost/hana/concept.hpp
+++ b/boost/hana/concept.hpp
@@ -18,6 +18,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/concept/foldable.hpp>
#include <boost/hana/concept/functor.hpp>
#include <boost/hana/concept/group.hpp>
+#include <boost/hana/concept/hashable.hpp>
#include <boost/hana/concept/integral_constant.hpp>
#include <boost/hana/concept/iterable.hpp>
#include <boost/hana/concept/logical.hpp>
diff --git a/boost/hana/concept/applicative.hpp b/boost/hana/concept/applicative.hpp
index 28c3af4242..9227b1d1d1 100644
--- a/boost/hana/concept/applicative.hpp
+++ b/boost/hana/concept/applicative.hpp
@@ -16,16 +16,18 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/lift.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename A>
- struct Applicative {
- using Tag = typename tag_of<A>::type;
- static constexpr bool value = !is_default<ap_impl<Tag>>::value &&
- !is_default<lift_impl<Tag>>::value;
- };
+ struct Applicative
+ : hana::integral_constant<bool,
+ !is_default<ap_impl<typename tag_of<A>::type>>::value &&
+ !is_default<lift_impl<typename tag_of<A>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_APPLICATIVE_HPP
diff --git a/boost/hana/concept/comonad.hpp b/boost/hana/concept/comonad.hpp
index 4aff1ab648..5d3a49a4e8 100644
--- a/boost/hana/concept/comonad.hpp
+++ b/boost/hana/concept/comonad.hpp
@@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/duplicate.hpp>
#include <boost/hana/extend.hpp>
#include <boost/hana/extract.hpp>
@@ -22,12 +23,13 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
template <typename W>
- struct Comonad {
- using Tag = typename tag_of<W>::type;
- static constexpr bool value = !is_default<extract_impl<Tag>>::value &&
- (!is_default<duplicate_impl<Tag>>::value ||
- !is_default<extend_impl<Tag>>::value);
- };
+ struct Comonad
+ : hana::integral_constant<bool,
+ !is_default<extract_impl<typename tag_of<W>::type>>::value &&
+ (!is_default<duplicate_impl<typename tag_of<W>::type>>::value ||
+ !is_default<extend_impl<typename tag_of<W>::type>>::value)
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_COMONAD_HPP
diff --git a/boost/hana/concept/comparable.hpp b/boost/hana/concept/comparable.hpp
index a38e5c6747..96c28be7e9 100644
--- a/boost/hana/concept/comparable.hpp
+++ b/boost/hana/concept/comparable.hpp
@@ -15,15 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/equal.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename T>
- struct Comparable {
- using Tag = typename tag_of<T>::type;
- static constexpr bool value = !is_default<equal_impl<Tag, Tag>>::value;
- };
+ struct Comparable
+ : hana::integral_constant<bool,
+ !is_default<equal_impl<typename tag_of<T>::type,
+ typename tag_of<T>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_COMPARABLE_HPP
diff --git a/boost/hana/concept/constant.hpp b/boost/hana/concept/constant.hpp
index 1c85a20739..08e5db248f 100644
--- a/boost/hana/concept/constant.hpp
+++ b/boost/hana/concept/constant.hpp
@@ -15,15 +15,17 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/value.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename C>
- struct Constant {
- using Tag = typename tag_of<C>::type;
- static constexpr bool value = !is_default<value_impl<Tag>>::value;
- };
+ struct Constant
+ : hana::integral_constant<bool,
+ !is_default<value_impl<typename tag_of<C>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_CONSTANT_HPP
diff --git a/boost/hana/concept/euclidean_ring.hpp b/boost/hana/concept/euclidean_ring.hpp
index 19ee1abcd5..c58cb9fc45 100644
--- a/boost/hana/concept/euclidean_ring.hpp
+++ b/boost/hana/concept/euclidean_ring.hpp
@@ -15,17 +15,21 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/div.hpp>
#include <boost/hana/mod.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename R>
- struct EuclideanRing {
- using Tag = typename tag_of<R>::type;
- static constexpr bool value = !is_default<mod_impl<Tag, Tag>>::value &&
- !is_default<div_impl<Tag, Tag>>::value;
- };
+ struct EuclideanRing
+ : hana::integral_constant<bool,
+ !is_default<mod_impl<typename tag_of<R>::type,
+ typename tag_of<R>::type>>::value &&
+ !is_default<div_impl<typename tag_of<R>::type,
+ typename tag_of<R>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_EUCLIDEAN_RING_HPP
diff --git a/boost/hana/concept/foldable.hpp b/boost/hana/concept/foldable.hpp
index 7737a74ce0..5efd153c2f 100644
--- a/boost/hana/concept/foldable.hpp
+++ b/boost/hana/concept/foldable.hpp
@@ -15,17 +15,19 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/fold_left.hpp>
#include <boost/hana/unpack.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename T>
- struct Foldable {
- using Tag = typename tag_of<T>::type;
- static constexpr bool value = !is_default<fold_left_impl<Tag>>::value ||
- !is_default<unpack_impl<Tag>>::value;
- };
+ struct Foldable
+ : hana::integral_constant<bool,
+ !is_default<fold_left_impl<typename tag_of<T>::type>>::value ||
+ !is_default<unpack_impl<typename tag_of<T>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_FOLDABLE_HPP
diff --git a/boost/hana/concept/functor.hpp b/boost/hana/concept/functor.hpp
index 308abae56f..1a84126f6f 100644
--- a/boost/hana/concept/functor.hpp
+++ b/boost/hana/concept/functor.hpp
@@ -12,20 +12,22 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/fwd/concept/functor.hpp>
-#include <boost/hana/config.hpp>
#include <boost/hana/adjust_if.hpp>
+#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/transform.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename F>
- struct Functor {
- using Tag = typename tag_of<F>::type;
- static constexpr bool value = !is_default<transform_impl<Tag>>::value ||
- !is_default<adjust_if_impl<Tag>>::value;
- };
+ struct Functor
+ : hana::integral_constant<bool,
+ !is_default<transform_impl<typename tag_of<F>::type>>::value ||
+ !is_default<adjust_if_impl<typename tag_of<F>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_FUNCTOR_HPP
diff --git a/boost/hana/concept/group.hpp b/boost/hana/concept/group.hpp
index 025537110a..5c8c34edf5 100644
--- a/boost/hana/concept/group.hpp
+++ b/boost/hana/concept/group.hpp
@@ -15,17 +15,20 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/minus.hpp>
#include <boost/hana/negate.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename G>
- struct Group {
- using Tag = typename tag_of<G>::type;
- static constexpr bool value = !is_default<negate_impl<Tag>>::value ||
- !is_default<minus_impl<Tag, Tag>>::value;
- };
+ struct Group
+ : hana::integral_constant<bool,
+ !is_default<negate_impl<typename tag_of<G>::type>>::value ||
+ !is_default<minus_impl<typename tag_of<G>::type,
+ typename tag_of<G>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_GROUP_HPP
diff --git a/boost/hana/concept/hashable.hpp b/boost/hana/concept/hashable.hpp
index 9fc282fb71..b5a0ca0feb 100644
--- a/boost/hana/concept/hashable.hpp
+++ b/boost/hana/concept/hashable.hpp
@@ -16,15 +16,17 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/hash.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename T>
- struct Hashable {
- using Tag = typename tag_of<T>::type;
- static constexpr bool value = !is_default<hash_impl<Tag>>::value;
- };
+ struct Hashable
+ : hana::integral_constant<bool,
+ !is_default<hash_impl<typename tag_of<T>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_HASHABLE_HPP
diff --git a/boost/hana/concept/integral_constant.hpp b/boost/hana/concept/integral_constant.hpp
index 6e36551001..599adf5bef 100644
--- a/boost/hana/concept/integral_constant.hpp
+++ b/boost/hana/concept/integral_constant.hpp
@@ -14,19 +14,22 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
BOOST_HANA_NAMESPACE_BEGIN
namespace detail {
template <typename C, typename Tag = typename tag_of<C>::type>
- struct integral_constant_dispatch {
- static constexpr bool value = hana::IntegralConstant<Tag>::value;
- };
+ struct integral_constant_dispatch
+ : hana::integral_constant<bool,
+ hana::IntegralConstant<Tag>::value
+ >
+ { };
template <typename C>
- struct integral_constant_dispatch<C, C> {
- static constexpr bool value = false;
- };
+ struct integral_constant_dispatch<C, C>
+ : hana::integral_constant<bool, false>
+ { };
}
//! @cond
diff --git a/boost/hana/concept/iterable.hpp b/boost/hana/concept/iterable.hpp
index 78c1914077..9cf68b7b43 100644
--- a/boost/hana/concept/iterable.hpp
+++ b/boost/hana/concept/iterable.hpp
@@ -12,22 +12,24 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/fwd/concept/iterable.hpp>
-#include <boost/hana/config.hpp>
#include <boost/hana/at.hpp>
+#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/drop_front.hpp>
#include <boost/hana/is_empty.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename It>
- struct Iterable {
- using Tag = typename tag_of<It>::type;
- static constexpr bool value = !is_default<at_impl<Tag>>::value &&
- !is_default<drop_front_impl<Tag>>::value &&
- !is_default<is_empty_impl<Tag>>::value;
- };
+ struct Iterable
+ : hana::integral_constant<bool,
+ !is_default<at_impl<typename tag_of<It>::type>>::value &&
+ !is_default<drop_front_impl<typename tag_of<It>::type>>::value &&
+ !is_default<is_empty_impl<typename tag_of<It>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_ITERABLE_HPP
diff --git a/boost/hana/concept/logical.hpp b/boost/hana/concept/logical.hpp
index 74c0fb3a51..ecfd0a4ebe 100644
--- a/boost/hana/concept/logical.hpp
+++ b/boost/hana/concept/logical.hpp
@@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/eval_if.hpp>
#include <boost/hana/not.hpp>
#include <boost/hana/while.hpp>
@@ -22,12 +23,13 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
template <typename L>
- struct Logical {
- using Tag = typename tag_of<L>::type;
- static constexpr bool value = !is_default<eval_if_impl<Tag>>::value &&
- !is_default<not_impl<Tag>>::value &&
- !is_default<while_impl<Tag>>::value;
- };
+ struct Logical
+ : hana::integral_constant<bool,
+ !is_default<eval_if_impl<typename tag_of<L>::type>>::value &&
+ !is_default<not_impl<typename tag_of<L>::type>>::value &&
+ !is_default<while_impl<typename tag_of<L>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_LOGICAL_HPP
diff --git a/boost/hana/concept/metafunction.hpp b/boost/hana/concept/metafunction.hpp
index ed6d53ad87..61713e2b2e 100644
--- a/boost/hana/concept/metafunction.hpp
+++ b/boost/hana/concept/metafunction.hpp
@@ -14,19 +14,22 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
BOOST_HANA_NAMESPACE_BEGIN
namespace detail {
template <typename F, typename Tag = typename tag_of<F>::type>
- struct metafunction_dispatch {
- static constexpr bool value = Metafunction<Tag>::value;
- };
+ struct metafunction_dispatch
+ : hana::integral_constant<bool,
+ Metafunction<Tag>::value
+ >
+ { };
template <typename F>
- struct metafunction_dispatch<F, F> {
- static constexpr bool value = false;
- };
+ struct metafunction_dispatch<F, F>
+ : hana::integral_constant<bool, false>
+ { };
}
template <typename F>
diff --git a/boost/hana/concept/monad.hpp b/boost/hana/concept/monad.hpp
index ba1c33021f..e586192b4a 100644
--- a/boost/hana/concept/monad.hpp
+++ b/boost/hana/concept/monad.hpp
@@ -16,16 +16,18 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/flatten.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename M>
- struct Monad {
- using Tag = typename tag_of<M>::type;
- static constexpr bool value = !is_default<flatten_impl<Tag>>::value ||
- !is_default<chain_impl<Tag>>::value;
- };
+ struct Monad
+ : hana::integral_constant<bool,
+ !is_default<flatten_impl<typename tag_of<M>::type>>::value ||
+ !is_default<chain_impl<typename tag_of<M>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_MONAD_HPP
diff --git a/boost/hana/concept/monad_plus.hpp b/boost/hana/concept/monad_plus.hpp
index 22c67ca255..c561e5af82 100644
--- a/boost/hana/concept/monad_plus.hpp
+++ b/boost/hana/concept/monad_plus.hpp
@@ -16,16 +16,18 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/empty.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename M>
- struct MonadPlus {
- using Tag = typename tag_of<M>::type;
- static constexpr bool value = !is_default<concat_impl<Tag>>::value &&
- !is_default<empty_impl<Tag>>::value;
- };
+ struct MonadPlus
+ : hana::integral_constant<bool,
+ !is_default<concat_impl<typename tag_of<M>::type>>::value &&
+ !is_default<empty_impl<typename tag_of<M>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_MONAD_PLUS_HPP
diff --git a/boost/hana/concept/monoid.hpp b/boost/hana/concept/monoid.hpp
index df84bb23e6..024ce4fe28 100644
--- a/boost/hana/concept/monoid.hpp
+++ b/boost/hana/concept/monoid.hpp
@@ -15,17 +15,20 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/plus.hpp>
#include <boost/hana/zero.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename M>
- struct Monoid {
- using Tag = typename tag_of<M>::type;
- static constexpr bool value = !is_default<zero_impl<Tag>>::value &&
- !is_default<plus_impl<Tag, Tag>>::value;
- };
+ struct Monoid
+ : hana::integral_constant<bool,
+ !is_default<zero_impl<typename tag_of<M>::type>>::value &&
+ !is_default<plus_impl<typename tag_of<M>::type,
+ typename tag_of<M>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_MONOID_HPP
diff --git a/boost/hana/concept/orderable.hpp b/boost/hana/concept/orderable.hpp
index 5461332cd4..1e9303d204 100644
--- a/boost/hana/concept/orderable.hpp
+++ b/boost/hana/concept/orderable.hpp
@@ -15,15 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/less.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename Ord>
- struct Orderable {
- using Tag = typename tag_of<Ord>::type;
- static constexpr bool value = !is_default<less_impl<Tag, Tag>>::value;
- };
+ struct Orderable
+ : hana::integral_constant<bool,
+ !is_default<less_impl<typename tag_of<Ord>::type,
+ typename tag_of<Ord>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_ORDERABLE_HPP
diff --git a/boost/hana/concept/product.hpp b/boost/hana/concept/product.hpp
index 1a77777b29..3ad8a70f2b 100644
--- a/boost/hana/concept/product.hpp
+++ b/boost/hana/concept/product.hpp
@@ -15,17 +15,19 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/first.hpp>
#include <boost/hana/second.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename P>
- struct Product {
- using Tag = typename tag_of<P>::type;
- static constexpr bool value = !is_default<first_impl<Tag>>::value &&
- !is_default<second_impl<Tag>>::value;
- };
+ struct Product
+ : hana::integral_constant<bool,
+ !is_default<first_impl<typename tag_of<P>::type>>::value &&
+ !is_default<second_impl<typename tag_of<P>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_PRODUCT_HPP
diff --git a/boost/hana/concept/ring.hpp b/boost/hana/concept/ring.hpp
index 3cc309e68a..700b3f6bb8 100644
--- a/boost/hana/concept/ring.hpp
+++ b/boost/hana/concept/ring.hpp
@@ -15,17 +15,20 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/mult.hpp>
#include <boost/hana/one.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename R>
- struct Ring {
- using Tag = typename tag_of<R>::type;
- static constexpr bool value = !is_default<one_impl<Tag>>::value &&
- !is_default<mult_impl<Tag, Tag>>::value;
- };
+ struct Ring
+ : hana::integral_constant<bool,
+ !is_default<one_impl<typename tag_of<R>::type>>::value &&
+ !is_default<mult_impl<typename tag_of<R>::type,
+ typename tag_of<R>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_RING_HPP
diff --git a/boost/hana/concept/searchable.hpp b/boost/hana/concept/searchable.hpp
index 923b57dfcf..0ee98907bf 100644
--- a/boost/hana/concept/searchable.hpp
+++ b/boost/hana/concept/searchable.hpp
@@ -16,16 +16,18 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <boost/hana/find_if.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename S>
- struct Searchable {
- using Tag = typename tag_of<S>::type;
- static constexpr bool value = !is_default<any_of_impl<Tag>>::value &&
- !is_default<find_if_impl<Tag>>::value;
- };
+ struct Searchable
+ : hana::integral_constant<bool,
+ !is_default<any_of_impl<typename tag_of<S>::type>>::value &&
+ !is_default<find_if_impl<typename tag_of<S>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_SEARCHABLE_HPP
diff --git a/boost/hana/concept/sequence.hpp b/boost/hana/concept/sequence.hpp
index b2c6cda50c..fb5b83a2de 100644
--- a/boost/hana/concept/sequence.hpp
+++ b/boost/hana/concept/sequence.hpp
@@ -15,19 +15,22 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/tag_of.hpp>
#include <boost/hana/core/when.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
BOOST_HANA_NAMESPACE_BEGIN
namespace detail {
template <typename S, typename Tag = typename hana::tag_of<S>::type>
- struct sequence_dispatch {
- static constexpr bool value = hana::Sequence<Tag>::value;
- };
+ struct sequence_dispatch
+ : hana::integral_constant<bool,
+ hana::Sequence<Tag>::value
+ >
+ { };
template <typename S>
- struct sequence_dispatch<S, S> {
- static constexpr bool value = false;
- };
+ struct sequence_dispatch<S, S>
+ : hana::integral_constant<bool, false>
+ { };
}
//! @cond
diff --git a/boost/hana/concept/struct.hpp b/boost/hana/concept/struct.hpp
index 709d0cccea..62183f44f6 100644
--- a/boost/hana/concept/struct.hpp
+++ b/boost/hana/concept/struct.hpp
@@ -16,14 +16,16 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/default.hpp>
#include <boost/hana/core/tag_of.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
BOOST_HANA_NAMESPACE_BEGIN
template <typename S>
- struct Struct {
- using Tag = typename tag_of<S>::type;
- static constexpr bool value = !is_default<accessors_impl<Tag>>::value;
- };
+ struct Struct
+ : hana::integral_constant<bool,
+ !is_default<accessors_impl<typename tag_of<S>::type>>::value
+ >
+ { };
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_CONCEPT_STRUCT_HPP
diff --git a/boost/hana/config.hpp b/boost/hana/config.hpp
index fd1939c09e..de7d1dc794 100644
--- a/boost/hana/config.hpp
+++ b/boost/hana/config.hpp
@@ -71,7 +71,11 @@ Distributed under the Boost Software License, Version 1.0.
// Check the compiler for general C++14 capabilities
//////////////////////////////////////////////////////////////////////////////
#if (__cplusplus < 201400)
-# warning "Your compiler doesn't provide C++14 or higher capabilities. Try adding the compiler flag '-std=c++14' or '-std=c++1y'."
+# if defined(_MSC_VER)
+# pragma message("Warning: Your compiler doesn't provide C++14 or higher capabilities. Try adding the compiler flag '-std=c++14' or '-std=c++1y'.")
+# else
+# warning "Your compiler doesn't provide C++14 or higher capabilities. Try adding the compiler flag '-std=c++14' or '-std=c++1y'."
+# endif
#endif
//////////////////////////////////////////////////////////////////////////////
diff --git a/boost/hana/detail/concepts.hpp b/boost/hana/detail/concepts.hpp
index 4031f356df..6feed772c0 100644
--- a/boost/hana/detail/concepts.hpp
+++ b/boost/hana/detail/concepts.hpp
@@ -33,7 +33,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail {
template <typename T, typename U>
struct EqualityComparable<T, U, typename std::enable_if<
- !std::is_same<T, U>{}, detail::void_t<
+ !std::is_same<T, U>::value, detail::void_t<
decltype(static_cast<T&&>(*(T*)0) == static_cast<U&&>(*(U*)0) ? 0:0),
decltype(static_cast<U&&>(*(U*)0) == static_cast<T&&>(*(T*)0) ? 0:0),
decltype(static_cast<T&&>(*(T*)0) != static_cast<U&&>(*(U*)0) ? 0:0),
diff --git a/boost/hana/detail/integral_constant.hpp b/boost/hana/detail/integral_constant.hpp
new file mode 100644
index 0000000000..aded3ba331
--- /dev/null
+++ b/boost/hana/detail/integral_constant.hpp
@@ -0,0 +1,245 @@
+/*!
+@file
+Defines the barebones `boost::hana::integral_constant` template, but no
+operations on it.
+
+@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_DETAIL_INTEGRAL_CONSTANT_HPP
+#define BOOST_HANA_DETAIL_INTEGRAL_CONSTANT_HPP
+
+#include <boost/hana/config.hpp>
+#include <boost/hana/detail/operators/adl.hpp>
+
+#include <type_traits>
+
+
+BOOST_HANA_NAMESPACE_BEGIN
+ //! Tag representing `hana::integral_constant`.
+ //! @relates hana::integral_constant
+ template <typename T>
+ struct integral_constant_tag {
+ using value_type = T;
+ };
+
+ namespace ic_detail {
+ template <typename T, T v>
+ struct with_index_t {
+ template <typename F>
+ constexpr void operator()(F&& f) const;
+ };
+
+ template <typename T, T v>
+ struct times_t {
+ static constexpr with_index_t<T, v> with_index{};
+
+ template <typename F>
+ constexpr void operator()(F&& f) const;
+ };
+ }
+
+ //! @ingroup group-datatypes
+ //! Compile-time value of an integral type.
+ //!
+ //! An `integral_constant` is an object that represents a compile-time
+ //! integral value. As the name suggests, `hana::integral_constant` is
+ //! basically equivalent to `std::integral_constant`, except that
+ //! `hana::integral_constant` also provide other goodies to make them
+ //! easier to use, like arithmetic operators and similar features. In
+ //! particular, `hana::integral_constant` is guaranteed to inherit from
+ //! the corresponding `std::integral_constant`, and hence have the same
+ //! members and capabilities. The sections below explain the extensions
+ //! to `std::integral_constant` provided by `hana::integral_constant`.
+ //!
+ //!
+ //! Arithmetic operators
+ //! --------------------
+ //! `hana::integral_constant` provides arithmetic operators that return
+ //! `hana::integral_constant`s to ease writing compile-time arithmetic:
+ //! @snippet example/integral_constant.cpp operators
+ //!
+ //! It is pretty important to realize that these operators return other
+ //! `integral_constant`s, not normal values of an integral type.
+ //! Actually, all those operators work pretty much in the same way.
+ //! Simply put, for an operator `@`,
+ //! @code
+ //! integral_constant<T, x>{} @ integral_constant<T, y>{} == integral_constant<T, x @ y>{}
+ //! @endcode
+ //!
+ //! The fact that the operators return `Constant`s is very important
+ //! because it allows all the information that's known at compile-time
+ //! to be conserved as long as it's only used with other values known at
+ //! compile-time. It is also interesting to observe that whenever an
+ //! `integral_constant` is combined with a normal runtime value, the
+ //! result will be a runtime value (because of the implicit conversion).
+ //! In general, this gives us the following table
+ //!
+ //! left operand | right operand | result
+ //! :-----------------: | :-----------------: | :-----------------:
+ //! `integral_constant` | `integral_constant` | `integral_constant`
+ //! `integral_constant` | runtime | runtime
+ //! runtime | `integral_constant` | runtime
+ //! runtime | runtime | runtime
+ //!
+ //! The full range of provided operators is
+ //! - Arithmetic: binary `+`, binary `-`, `/`, `*`, `%`, unary `+`, unary `-`
+ //! - Bitwise: `~`, `&`, `|`, `^`, `<<`, `>>`
+ //! - Comparison: `==`, `!=`, `<`, `<=`, `>`, `>=`
+ //! - %Logical: `||`, `&&`, `!`
+ //!
+ //!
+ //! Construction with user-defined literals
+ //! ---------------------------------------
+ //! `integral_constant`s of type `long long` can be created with the
+ //! `_c` user-defined literal, which is contained in the `literals`
+ //! namespace:
+ //! @snippet example/integral_constant.cpp literals
+ //!
+ //!
+ //! Modeled concepts
+ //! ----------------
+ //! 1. `Constant` and `IntegralConstant`\n
+ //! An `integral_constant` is a model of the `IntegralConstant` concept in
+ //! the most obvious way possible. Specifically,
+ //! @code
+ //! integral_constant<T, v>::value == v // of type T
+ //! @endcode
+ //! The model of `Constant` follows naturally from the model of `IntegralConstant`, i.e.
+ //! @code
+ //! value<integral_constant<T, v>>() == v // of type T
+ //! @endcode
+ //!
+ //! 2. `Comparable`, `Orderable`, `Logical`, `Monoid`, `Group`, `Ring`, and `EuclideanRing`, `Hashable`\n
+ //! Those models are exactly those provided for `Constant`s, which are
+ //! documented in their respective concepts.
+#ifdef BOOST_HANA_DOXYGEN_INVOKED
+ template <typename T, T v>
+ struct integral_constant {
+ //! Call a function n times.
+ //!
+ //! `times` allows a nullary function to be invoked `n` times:
+ //! @code
+ //! int_<3>::times(f)
+ //! @endcode
+ //! should be expanded by any decent compiler to
+ //! @code
+ //! f(); f(); f();
+ //! @endcode
+ //!
+ //! This can be useful in several contexts, e.g. for loop unrolling:
+ //! @snippet example/integral_constant.cpp times_loop_unrolling
+ //!
+ //! Note that `times` is really a static function object, not just a
+ //! static function. This allows `int_<n>::%times` to be passed to
+ //! higher-order algorithms:
+ //! @snippet example/integral_constant.cpp times_higher_order
+ //!
+ //! Also, since static members can be accessed using both the `.` and
+ //! the `::` syntax, one can take advantage of this (loophole?) to
+ //! call `times` on objects just as well as on types:
+ //! @snippet example/integral_constant.cpp from_object
+ //!
+ //! @note
+ //! `times` is equivalent to the `hana::repeat` function, which works
+ //! on an arbitrary `IntegralConstant`.
+ //!
+ //! Sometimes, it is also useful to know the index we're at inside the
+ //! function. This can be achieved by using `times.with_index`:
+ //! @snippet example/integral_constant.cpp times_with_index_runtime
+ //!
+ //! Remember that `times` is a _function object_, and hence it can
+ //! have subobjects. `with_index` is just a function object nested
+ //! inside `times`, which allows for this nice little interface. Also
+ //! note that the indices passed to the function are `integral_constant`s;
+ //! they are known at compile-time. Hence, we can do compile-time stuff
+ //! with them, like indexing inside a tuple:
+ //! @snippet example/integral_constant.cpp times_with_index_compile_time
+ //!
+ //! @note
+ //! `times.with_index(f)` guarantees that the calls to `f` will be
+ //! done in order of ascending index. In other words, `f` will be
+ //! called as `f(0)`, `f(1)`, `f(2)`, etc., but with `integral_constant`s
+ //! instead of normal integers. Side effects can also be done in the
+ //! function passed to `times` and `times.with_index`.
+ template <typename F>
+ static constexpr void times(F&& f) {
+ f(); f(); ... f(); // n times total
+ }
+
+ //! Equivalent to `hana::plus`
+ template <typename X, typename Y>
+ friend constexpr auto operator+(X&& x, Y&& y);
+
+ //! Equivalent to `hana::minus`
+ template <typename X, typename Y>
+ friend constexpr auto operator-(X&& x, Y&& y);
+
+ //! Equivalent to `hana::negate`
+ template <typename X>
+ friend constexpr auto operator-(X&& x);
+
+ //! Equivalent to `hana::mult`
+ template <typename X, typename Y>
+ friend constexpr auto operator*(X&& x, Y&& y);
+
+ //! Equivalent to `hana::div`
+ template <typename X, typename Y>
+ friend constexpr auto operator/(X&& x, Y&& y);
+
+ //! Equivalent to `hana::mod`
+ template <typename X, typename Y>
+ friend constexpr auto operator%(X&& x, Y&& y);
+
+ //! Equivalent to `hana::equal`
+ template <typename X, typename Y>
+ friend constexpr auto operator==(X&& x, Y&& y);
+
+ //! Equivalent to `hana::not_equal`
+ template <typename X, typename Y>
+ friend constexpr auto operator!=(X&& x, Y&& y);
+
+ //! Equivalent to `hana::or_`
+ template <typename X, typename Y>
+ friend constexpr auto operator||(X&& x, Y&& y);
+
+ //! Equivalent to `hana::and_`
+ template <typename X, typename Y>
+ friend constexpr auto operator&&(X&& x, Y&& y);
+
+ //! Equivalent to `hana::not_`
+ template <typename X>
+ friend constexpr auto operator!(X&& x);
+
+ //! Equivalent to `hana::less`
+ template <typename X, typename Y>
+ friend constexpr auto operator<(X&& x, Y&& y);
+
+ //! Equivalent to `hana::greater`
+ template <typename X, typename Y>
+ friend constexpr auto operator>(X&& x, Y&& y);
+
+ //! Equivalent to `hana::less_equal`
+ template <typename X, typename Y>
+ friend constexpr auto operator<=(X&& x, Y&& y);
+
+ //! Equivalent to `hana::greater_equal`
+ template <typename X, typename Y>
+ friend constexpr auto operator>=(X&& x, Y&& y);
+ };
+#else
+ template <typename T, T v>
+ struct integral_constant
+ : std::integral_constant<T, v>
+ , detail::operators::adl<integral_constant<T, v>>
+ {
+ using type = integral_constant; // override std::integral_constant::type
+ static constexpr ic_detail::times_t<T, v> times{};
+ using hana_tag = integral_constant_tag<T>;
+ };
+#endif
+BOOST_HANA_NAMESPACE_END
+
+#endif // !BOOST_HANA_DETAIL_INTEGRAL_CONSTANT_HPP
diff --git a/boost/hana/detail/type_at.hpp b/boost/hana/detail/type_at.hpp
new file mode 100644
index 0000000000..5875483d24
--- /dev/null
+++ b/boost/hana/detail/type_at.hpp
@@ -0,0 +1,57 @@
+/*!
+@file
+Defines `boost::hana::detail::type_at`.
+
+@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_DETAIL_TYPE_AT_HPP
+#define BOOST_HANA_DETAIL_TYPE_AT_HPP
+
+#include <boost/hana/config.hpp>
+
+#include <cstddef>
+#include <utility>
+
+
+// If possible, use an intrinsic provided by Clang
+#if defined(__has_builtin)
+# if __has_builtin(__type_pack_element)
+# define BOOST_HANA_USE_TYPE_PACK_ELEMENT_INTRINSIC
+# endif
+#endif
+
+BOOST_HANA_NAMESPACE_BEGIN namespace detail {
+ namespace td {
+ template <std::size_t I, typename T>
+ struct elt { using type = T; };
+
+ template <typename Indices, typename ...T>
+ struct indexer;
+
+ template <std::size_t ...I, typename ...T>
+ struct indexer<std::index_sequence<I...>, T...>
+ : elt<I, T>...
+ { };
+
+ template <std::size_t I, typename T>
+ elt<I, T> get_elt(elt<I, T> const&);
+ }
+
+ //! @ingroup group-details
+ //! Classic MPL-style metafunction returning the nth element of a type
+ //! parameter pack.
+ template <std::size_t n, typename ...T>
+ struct type_at {
+#if defined(BOOST_HANA_USE_TYPE_PACK_ELEMENT_INTRINSIC)
+ using type = __type_pack_element<n, T...>;
+#else
+ using Indexer = td::indexer<std::make_index_sequence<sizeof...(T)>, T...>;
+ using type = typename decltype(td::get_elt<n>(Indexer{}))::type;
+#endif
+ };
+} BOOST_HANA_NAMESPACE_END
+
+#endif // !BOOST_HANA_DETAIL_TYPE_AT_HPP
diff --git a/boost/hana/drop_front.hpp b/boost/hana/drop_front.hpp
index 053a2f2b13..c06fbec593 100644
--- a/boost/hana/drop_front.hpp
+++ b/boost/hana/drop_front.hpp
@@ -43,7 +43,7 @@ BOOST_HANA_NAMESPACE_BEGIN
template <typename Xs>
constexpr auto drop_front_t::operator()(Xs&& xs) const {
- return (*this)(static_cast<Xs&&>(xs), hana::size_c<1>);
+ return (*this)(static_cast<Xs&&>(xs), hana::size_t<1>{});
}
//! @endcond
diff --git a/boost/hana/equal.hpp b/boost/hana/equal.hpp
index 498f7a8a2b..8eb0912fca 100644
--- a/boost/hana/equal.hpp
+++ b/boost/hana/equal.hpp
@@ -63,7 +63,11 @@ BOOST_HANA_NAMESPACE_BEGIN
"types that can't be safely embedded into a common type, because "
"those are most likely programming errors. If this is really what "
"you want, you can manually convert both objects to a common "
- "Comparable type before performing the comparison.");
+ "Comparable type before performing the comparison. If you think "
+ "you have made your types Comparable but you see this, perhaps you "
+ "forgot to define some of the necessary methods for an automatic "
+ "model of Comparable to kick in. A possible culprit is defining "
+ "'operator==' but not 'operator!='.");
return hana::false_c;
}
@@ -105,7 +109,7 @@ BOOST_HANA_NAMESPACE_BEGIN
static constexpr auto apply(X const&, Y const&) {
constexpr auto eq = hana::equal(hana::value<X>(), hana::value<Y>());
constexpr bool truth_value = hana::if_(eq, true, false);
- return hana::bool_c<truth_value>;
+ return hana::bool_<truth_value>{};
}
};
@@ -135,7 +139,7 @@ BOOST_HANA_NAMESPACE_BEGIN
template <std::size_t i>
constexpr auto apply(hana::false_, hana::true_) const {
return compare_finite_sequences::apply<i+1>(
- hana::bool_c<i+1 == Length>,
+ hana::bool_<i+1 == Length>{},
hana::if_(hana::equal(hana::at_c<i>(xs), hana::at_c<i>(ys)),
hana::true_c, hana::false_c)
);
@@ -152,7 +156,7 @@ BOOST_HANA_NAMESPACE_BEGIN
template <std::size_t i>
constexpr bool apply(hana::false_, bool b) const {
return b && compare_finite_sequences::apply<i+1>(
- hana::bool_c<i+1 == Length>,
+ hana::bool_<i+1 == Length>{},
hana::if_(hana::equal(hana::at_c<i>(xs), hana::at_c<i>(ys)),
hana::true_c, hana::false_c)
);
@@ -167,8 +171,8 @@ BOOST_HANA_NAMESPACE_BEGIN
constexpr std::size_t xs_size = decltype(hana::length(xs))::value;
constexpr std::size_t ys_size = decltype(hana::length(ys))::value;
detail::compare_finite_sequences<Xs, Ys, xs_size> comp{xs, ys};
- return comp.template apply<0>(hana::bool_c<xs_size == 0>,
- hana::bool_c<xs_size == ys_size>);
+ return comp.template apply<0>(hana::bool_<xs_size == 0>{},
+ hana::bool_<xs_size == ys_size>{});
}
};
diff --git a/boost/hana/experimental/printable.hpp b/boost/hana/experimental/printable.hpp
index 20993740dd..240e3a9291 100644
--- a/boost/hana/experimental/printable.hpp
+++ b/boost/hana/experimental/printable.hpp
@@ -41,6 +41,9 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN namespace experimental {
+ template <typename T>
+ struct Printable;
+
//! @cond
template <typename T, typename = void>
struct print_impl : print_impl<T, hana::when<true>> { };
@@ -70,7 +73,16 @@ BOOST_HANA_NAMESPACE_BEGIN namespace experimental {
struct print_t {
template <typename T>
std::string operator()(T const& t) const {
- using Print = print_impl<typename hana::tag_of<T>::type>;
+ using Tag = typename hana::tag_of<T>::type;
+ using Print = BOOST_HANA_DISPATCH_IF(print_impl<Tag>,
+ hana::experimental::Printable<Tag>::value
+ );
+
+ #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
+ static_assert(hana::experimental::Printable<Tag>::value,
+ "hana::experimental::print(t) requires 't' to be Printable");
+ #endif
+
return Print::apply(t);
}
};
diff --git a/boost/hana/experimental/type_name.hpp b/boost/hana/experimental/type_name.hpp
new file mode 100644
index 0000000000..764b7eedd9
--- /dev/null
+++ b/boost/hana/experimental/type_name.hpp
@@ -0,0 +1,64 @@
+/*
+@file
+Defines `boost::hana::experimental::type_name`.
+
+@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_EXPERIMENTAL_TYPE_NAME_HPP
+#define BOOST_HANA_EXPERIMENTAL_TYPE_NAME_HPP
+
+#include <boost/hana/config.hpp>
+#include <boost/hana/string.hpp>
+
+#include <cstddef>
+#include <utility>
+
+
+BOOST_HANA_NAMESPACE_BEGIN namespace experimental {
+ namespace detail {
+ struct cstring {
+ char const* ptr;
+ std::size_t length;
+ };
+
+ // Note: We substract the null terminator from the string sizes below.
+ template <typename T>
+ constexpr cstring type_name_impl2() {
+
+ #if defined(__clang__)
+ constexpr char const* pretty_function = __PRETTY_FUNCTION__;
+ constexpr std::size_t total_size = sizeof(__PRETTY_FUNCTION__) - 1;
+ constexpr std::size_t prefix_size = sizeof("boost::hana::experimental::detail::cstring boost::hana::experimental::detail::type_name_impl2() [T = ") - 1;
+ constexpr std::size_t suffix_size = sizeof("]") - 1;
+ #else
+ #error "No support for this compiler."
+ #endif
+
+ return {pretty_function + prefix_size, total_size - prefix_size - suffix_size};
+ }
+
+ template <typename T, std::size_t ...i>
+ auto type_name_impl1(std::index_sequence<i...>) {
+ constexpr auto name = detail::type_name_impl2<T>();
+ return hana::string<*(name.ptr + i)...>{};
+ }
+ } // end namespace detail
+
+ //! @ingroup group-experimental
+ //! Returns a `hana::string` representing the name of the given type, at
+ //! compile-time.
+ //!
+ //! This only works on Clang (and apparently MSVC, but Hana does not work
+ //! there as of writing this). Original idea taken from
+ //! https://github.com/Manu343726/ctti.
+ template <typename T>
+ auto type_name() {
+ constexpr auto name = detail::type_name_impl2<T>();
+ return detail::type_name_impl1<T>(std::make_index_sequence<name.length>{});
+ }
+} BOOST_HANA_NAMESPACE_END
+
+#endif // !BOOST_HANA_EXPERIMENTAL_TYPE_NAME_HPP
diff --git a/boost/hana/experimental/types.hpp b/boost/hana/experimental/types.hpp
index 86d9ddc957..75ae99e4f6 100644
--- a/boost/hana/experimental/types.hpp
+++ b/boost/hana/experimental/types.hpp
@@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/concept/metafunction.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/detail/any_of.hpp>
+#include <boost/hana/detail/type_at.hpp>
#include <boost/hana/fwd/at.hpp>
#include <boost/hana/fwd/contains.hpp>
#include <boost/hana/fwd/core/tag_of.hpp>
@@ -43,8 +44,6 @@ BOOST_HANA_NAMESPACE_BEGIN
struct types_tag;
- //////////////////////////////////////////////////////////////////////
-
template <typename ...T>
struct types { };
} // end namespace experimental
@@ -88,30 +87,13 @@ BOOST_HANA_NAMESPACE_BEGIN
apply(hana::experimental::types<T...> const&, F const&) { return {}; }
};
- namespace types_detail {
- template <std::size_t I, typename T>
- struct elt { using type = T; };
-
- template <typename Indices, typename ...T>
- struct indexer;
-
- template <std::size_t ...I, typename ...T>
- struct indexer<std::index_sequence<I...>, T...>
- : elt<I, T>...
- { };
-
- template <std::size_t I, typename T>
- elt<I, T> get_elt(elt<I, T> const&);
- }
-
// Iterable
template <>
struct at_impl<hana::experimental::types_tag> {
template <typename ...T, typename N>
static constexpr auto
apply(hana::experimental::types<T...> const&, N const&) {
- using Indexer = types_detail::indexer<std::make_index_sequence<sizeof...(T)>, T...>;
- using Nth = typename decltype(types_detail::get_elt<N::value>(Indexer{}))::type;
+ using Nth = typename detail::type_at<N::value, T...>::type;
return hana::type<Nth>{};
}
};
@@ -126,18 +108,16 @@ BOOST_HANA_NAMESPACE_BEGIN
template <>
struct drop_front_impl<hana::experimental::types_tag> {
- template <std::size_t n, typename Indexer, std::size_t ...i>
- static hana::experimental::types<
- typename decltype(types_detail::get_elt<i + n>(Indexer{}))::type...
- > helper(std::index_sequence<i...>);
+ template <std::size_t n, typename ...T, std::size_t ...i>
+ static hana::experimental::types<typename detail::type_at<i + n, T...>::type...>
+ helper(std::index_sequence<i...>);
template <typename ...T, typename N>
static constexpr auto
apply(hana::experimental::types<T...> const&, N const&) {
constexpr std::size_t n = N::value > sizeof...(T) ? sizeof...(T) : N::value;
using Indices = std::make_index_sequence<sizeof...(T) - n>;
- using Indexer = types_detail::indexer<std::make_index_sequence<sizeof...(T)>, T...>;
- return decltype(helper<n, Indexer>(Indices{})){};
+ return decltype(helper<n, T...>(Indices{})){};
}
};
diff --git a/boost/hana/ext/std/array.hpp b/boost/hana/ext/std/array.hpp
index f733624e57..15365f59cd 100644
--- a/boost/hana/ext/std/array.hpp
+++ b/boost/hana/ext/std/array.hpp
@@ -93,7 +93,7 @@ BOOST_HANA_NAMESPACE_BEGIN
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];
+ return std::get<n>(static_cast<Xs&&>(xs));
}
};
diff --git a/boost/hana/ext/std/integral_constant.hpp b/boost/hana/ext/std/integral_constant.hpp
index 28d8f05fb8..48db42400c 100644
--- a/boost/hana/ext/std/integral_constant.hpp
+++ b/boost/hana/ext/std/integral_constant.hpp
@@ -85,7 +85,7 @@ BOOST_HANA_NAMESPACE_BEGIN
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>{}> {
+ >> : embedding<is_embedded<typename C::value_type, T>::value> {
template <typename N>
static constexpr auto apply(N const&) {
return std::integral_constant<T, N::value>{};
diff --git a/boost/hana/fwd/concept/comparable.hpp b/boost/hana/fwd/concept/comparable.hpp
index 1d4df7d635..555dfdfa34 100644
--- a/boost/hana/fwd/concept/comparable.hpp
+++ b/boost/hana/fwd/concept/comparable.hpp
@@ -49,14 +49,13 @@ BOOST_HANA_NAMESPACE_BEGIN
//! Laws
//! ----
//! `equal` must define an [equivalence relation][1], and `not_equal` must
- //! be its complement. In other words, for all objects `a`, `b`, `c` of a
- //! `Comparable` tag, the following must be true (where `x == y` and
- //! `x != y` denote `equal(x, y)` and `not_equal(x, y)`, respectively):
+ //! be its complement. In other words, for all objects `a`, `b`, `c` with
+ //! a `Comparable` tag, the following must hold:
//! @code
- //! a == a // Reflexivity
- //! if a == b then b == a // Symmetry
- //! if a == b && b == c then a == c // Transitivity
- //! a != b is equivalent to !(a == b)
+ //! equal(a, a) // Reflexivity
+ //! if equal(a, b) then equal(b, a) // Symmetry
+ //! if equal(a, b) && equal(b, c) then equal(a, c) // Transitivity
+ //! not_equal(a, b) is equivalent to not_(equal(a, b))
//! @endcode
//!
//!
diff --git a/boost/hana/fwd/integral_constant.hpp b/boost/hana/fwd/integral_constant.hpp
index e04eb8865d..d05d6021f9 100644
--- a/boost/hana/fwd/integral_constant.hpp
+++ b/boost/hana/fwd/integral_constant.hpp
@@ -11,236 +11,12 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_HANA_FWD_INTEGRAL_CONSTANT_HPP
#include <boost/hana/config.hpp>
-#include <boost/hana/detail/operators/adl.hpp>
+#include <boost/hana/detail/integral_constant.hpp>
#include <cstddef>
-#include <type_traits>
BOOST_HANA_NAMESPACE_BEGIN
- //! Tag representing `hana::integral_constant`.
- //! @relates hana::integral_constant
- template <typename T>
- struct integral_constant_tag {
- using value_type = T;
- };
-
- namespace ic_detail {
- template <typename T, T v>
- struct with_index_t {
- template <typename F>
- constexpr void operator()(F&& f) const;
- };
-
- template <typename T, T v>
- struct times_t {
- static constexpr with_index_t<T, v> with_index{};
-
- template <typename F>
- constexpr void operator()(F&& f) const;
- };
- }
-
- //! @ingroup group-datatypes
- //! Compile-time value of an integral type.
- //!
- //! An `integral_constant` is an object that represents a compile-time
- //! integral value. As the name suggests, `hana::integral_constant` is
- //! basically equivalent to `std::integral_constant`, except that
- //! `hana::integral_constant` also provide other goodies to make them
- //! easier to use, like arithmetic operators and similar features. In
- //! particular, `hana::integral_constant` is guaranteed to inherit from
- //! the corresponding `std::integral_constant`, and hence have the same
- //! members and capabilities. The sections below explain the extensions
- //! to `std::integral_constant` provided by `hana::integral_constant`.
- //!
- //!
- //! Arithmetic operators
- //! --------------------
- //! `hana::integral_constant` provides arithmetic operators that return
- //! `hana::integral_constant`s to ease writing compile-time arithmetic:
- //! @snippet example/integral_constant.cpp operators
- //!
- //! It is pretty important to realize that these operators return other
- //! `integral_constant`s, not normal values of an integral type.
- //! Actually, all those operators work pretty much in the same way.
- //! Simply put, for an operator `@`,
- //! @code
- //! integral_constant<T, x>{} @ integral_constant<T, y>{} == integral_constant<T, x @ y>{}
- //! @endcode
- //!
- //! The fact that the operators return `Constant`s is very important
- //! because it allows all the information that's known at compile-time
- //! to be conserved as long as it's only used with other values known at
- //! compile-time. It is also interesting to observe that whenever an
- //! `integral_constant` is combined with a normal runtime value, the
- //! result will be a runtime value (because of the implicit conversion).
- //! In general, this gives us the following table
- //!
- //! left operand | right operand | result
- //! :-----------------: | :-----------------: | :-----------------:
- //! `integral_constant` | `integral_constant` | `integral_constant`
- //! `integral_constant` | runtime | runtime
- //! runtime | `integral_constant` | runtime
- //! runtime | runtime | runtime
- //!
- //! The full range of provided operators is
- //! - Arithmetic: binary `+`, binary `-`, `/`, `*`, `%`, unary `+`, unary `-`
- //! - Bitwise: `~`, `&`, `|`, `^`, `<<`, `>>`
- //! - Comparison: `==`, `!=`, `<`, `<=`, `>`, `>=`
- //! - %Logical: `||`, `&&`, `!`
- //!
- //!
- //! Construction with user-defined literals
- //! ---------------------------------------
- //! `integral_constant`s of type `long long` can be created with the
- //! `_c` user-defined literal, which is contained in the `literals`
- //! namespace:
- //! @snippet example/integral_constant.cpp literals
- //!
- //!
- //! Modeled concepts
- //! ----------------
- //! 1. `Constant` and `IntegralConstant`\n
- //! An `integral_constant` is a model of the `IntegralConstant` concept in
- //! the most obvious way possible. Specifically,
- //! @code
- //! integral_constant<T, v>::value == v // of type T
- //! @endcode
- //! The model of `Constant` follows naturally from the model of `IntegralConstant`, i.e.
- //! @code
- //! value<integral_constant<T, v>>() == v // of type T
- //! @endcode
- //!
- //! 2. `Comparable`, `Orderable`, `Logical`, `Monoid`, `Group`, `Ring`, and `EuclideanRing`, `Hashable`\n
- //! Those models are exactly those provided for `Constant`s, which are
- //! documented in their respective concepts.
-#ifdef BOOST_HANA_DOXYGEN_INVOKED
- template <typename T, T v>
- struct integral_constant {
- //! Call a function n times.
- //!
- //! `times` allows a nullary function to be invoked `n` times:
- //! @code
- //! int_<3>::times(f)
- //! @endcode
- //! should be expanded by any decent compiler to
- //! @code
- //! f(); f(); f();
- //! @endcode
- //!
- //! This can be useful in several contexts, e.g. for loop unrolling:
- //! @snippet example/integral_constant.cpp times_loop_unrolling
- //!
- //! Note that `times` is really a static function object, not just a
- //! static function. This allows `int_<n>::%times` to be passed to
- //! higher-order algorithms:
- //! @snippet example/integral_constant.cpp times_higher_order
- //!
- //! Also, since static members can be accessed using both the `.` and
- //! the `::` syntax, one can take advantage of this (loophole?) to
- //! call `times` on objects just as well as on types:
- //! @snippet example/integral_constant.cpp from_object
- //!
- //! @note
- //! `times` is equivalent to the `hana::repeat` function, which works
- //! on an arbitrary `IntegralConstant`.
- //!
- //! Sometimes, it is also useful to know the index we're at inside the
- //! function. This can be achieved by using `times.with_index`:
- //! @snippet example/integral_constant.cpp times_with_index_runtime
- //!
- //! Remember that `times` is a _function object_, and hence it can
- //! have subobjects. `with_index` is just a function object nested
- //! inside `times`, which allows for this nice little interface. Also
- //! note that the indices passed to the function are `integral_constant`s;
- //! they are known at compile-time. Hence, we can do compile-time stuff
- //! with them, like indexing inside a tuple:
- //! @snippet example/integral_constant.cpp times_with_index_compile_time
- //!
- //! @note
- //! `times.with_index(f)` guarantees that the calls to `f` will be
- //! done in order of ascending index. In other words, `f` will be
- //! called as `f(0)`, `f(1)`, `f(2)`, etc., but with `integral_constant`s
- //! instead of normal integers. Side effects can also be done in the
- //! function passed to `times` and `times.with_index`.
- template <typename F>
- static constexpr void times(F&& f) {
- f(); f(); ... f(); // n times total
- }
-
- //! Equivalent to `hana::plus`
- template <typename X, typename Y>
- friend constexpr auto operator+(X&& x, Y&& y);
-
- //! Equivalent to `hana::minus`
- template <typename X, typename Y>
- friend constexpr auto operator-(X&& x, Y&& y);
-
- //! Equivalent to `hana::negate`
- template <typename X>
- friend constexpr auto operator-(X&& x);
-
- //! Equivalent to `hana::mult`
- template <typename X, typename Y>
- friend constexpr auto operator*(X&& x, Y&& y);
-
- //! Equivalent to `hana::div`
- template <typename X, typename Y>
- friend constexpr auto operator/(X&& x, Y&& y);
-
- //! Equivalent to `hana::mod`
- template <typename X, typename Y>
- friend constexpr auto operator%(X&& x, Y&& y);
-
- //! Equivalent to `hana::equal`
- template <typename X, typename Y>
- friend constexpr auto operator==(X&& x, Y&& y);
-
- //! Equivalent to `hana::not_equal`
- template <typename X, typename Y>
- friend constexpr auto operator!=(X&& x, Y&& y);
-
- //! Equivalent to `hana::or_`
- template <typename X, typename Y>
- friend constexpr auto operator||(X&& x, Y&& y);
-
- //! Equivalent to `hana::and_`
- template <typename X, typename Y>
- friend constexpr auto operator&&(X&& x, Y&& y);
-
- //! Equivalent to `hana::not_`
- template <typename X>
- friend constexpr auto operator!(X&& x);
-
- //! Equivalent to `hana::less`
- template <typename X, typename Y>
- friend constexpr auto operator<(X&& x, Y&& y);
-
- //! Equivalent to `hana::greater`
- template <typename X, typename Y>
- friend constexpr auto operator>(X&& x, Y&& y);
-
- //! Equivalent to `hana::less_equal`
- template <typename X, typename Y>
- friend constexpr auto operator<=(X&& x, Y&& y);
-
- //! Equivalent to `hana::greater_equal`
- template <typename X, typename Y>
- friend constexpr auto operator>=(X&& x, Y&& y);
- };
-#else
- template <typename T, T v>
- struct integral_constant
- : std::integral_constant<T, v>
- , detail::operators::adl<integral_constant<T, v>>
- {
- using type = integral_constant; // override std::integral_constant::type
- static constexpr ic_detail::times_t<T, v> times{};
- using hana_tag = integral_constant_tag<T>;
- };
-#endif
-
//! Creates an `integral_constant` holding the given compile-time value.
//! @relates hana::integral_constant
//!
diff --git a/boost/hana/fwd/map.hpp b/boost/hana/fwd/map.hpp
index 707cc0c6e9..25ff7add35 100644
--- a/boost/hana/fwd/map.hpp
+++ b/boost/hana/fwd/map.hpp
@@ -17,8 +17,14 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/fwd/insert.hpp>
#include <boost/hana/fwd/keys.hpp>
+#include <utility>
+
BOOST_HANA_NAMESPACE_BEGIN
+ //! Tag representing `hana::map`s.
+ //! @relates hana::map
+ struct map_tag { };
+
//! @ingroup group-datatypes
//! Basic associative container requiring unique, `Comparable` and
//! `Hashable` keys.
@@ -27,12 +33,21 @@ BOOST_HANA_NAMESPACE_BEGIN
//! keys must be `Hashable`, and any two keys with equal hashes must be
//! `Comparable` with each other at compile-time.
//!
- //! @note
- //! The actual representation of a `hana::map` is implementation-defined.
- //! In particular, one should not take for granted the order of the
- //! template parameters and the presence of any additional constructors
- //! or assignment operators than what is documented. The canonical way of
- //! creating a `hana::map` is through `hana::make_map`.
+ //! Note that the actual representation of a `hana::map` is an implementation
+ //! detail. As such, one should not assume anything more than what is
+ //! explicitly documented as being part of the interface of a map,
+ //! such as:
+ //! - the presence of additional constructors
+ //! - the presence of additional assignment operators
+ //! - the fact that `hana::map<Pairs...>` is, or is not, a dependent type
+ //!
+ //! In particular, the last point is very important; `hana::map<Pairs...>`
+ //! is only a shortcut for
+ //! @code
+ //! decltype(hana::make_pair(std::declval<Pairs>()...))
+ //! @endcode
+ //! which is not something that can be pattern-matched on during template
+ //! argument deduction, for example.
//!
//!
//! Modeled concepts
@@ -63,8 +78,13 @@ BOOST_HANA_NAMESPACE_BEGIN
//! `Foldable` contains duplicate keys, only the value associated to the
//! first occurence of each key is kept.
//! @include example/map/to.cpp
+ //!
+ //!
+ //! Example
+ //! -------
+ //! @include example/map/map.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
- template <typename implementation_defined>
+ template <typename ...Pairs>
struct map {
//! Default-construct a map. This constructor only exists when all the
//! elements of the map are default-constructible.
@@ -78,6 +98,14 @@ BOOST_HANA_NAMESPACE_BEGIN
//! exists when all the elements of the map are move-constructible.
constexpr map(map&& other) = default;
+ //! Construct the map from the provided pairs. `P...` must be pairs of
+ //! the same type (modulo ref and cv-qualifiers), and in the same order,
+ //! as those appearing in `Pairs...`. The pairs provided to this
+ //! constructor are emplaced into the map's storage using perfect
+ //! forwarding.
+ template <typename ...P>
+ explicit constexpr map(P&& ...pairs);
+
//! Equivalent to `hana::equal`
template <typename X, typename Y>
friend constexpr auto operator==(X&& x, Y&& y);
@@ -91,14 +119,10 @@ BOOST_HANA_NAMESPACE_BEGIN
constexpr decltype(auto) operator[](Key&& key);
};
#else
- template <typename HashTable, typename Storage>
- struct map;
+ template <typename ...Pairs>
+ using map = decltype(hana::make<map_tag>(std::declval<Pairs>()...));
#endif
- //! Tag representing `hana::map`s.
- //! @relates hana::map
- struct map_tag { };
-
//! Function object for creating a `hana::map`.
//! @relates hana::map
//!
diff --git a/boost/hana/fwd/string.hpp b/boost/hana/fwd/string.hpp
index f96494b165..c3476d7e72 100644
--- a/boost/hana/fwd/string.hpp
+++ b/boost/hana/fwd/string.hpp
@@ -38,8 +38,8 @@ BOOST_HANA_NAMESPACE_BEGIN
//! The representation of `hana::string` is implementation-defined.
//! In particular, one should not take for granted that the template
//! parameters are `char`s. The proper way to access the contents of
- //! a `hana::string` as character constants is to use `hana::unpack`
- //! or `hana::to<char const*>`, as documented below.
+ //! a `hana::string` as character constants is to use `hana::unpack`,
+ //! `.c_str()` or `hana::to<char const*>`, as documented below.
//!
//!
//! Modeled concepts
@@ -57,23 +57,28 @@ BOOST_HANA_NAMESPACE_BEGIN
//! lexicographical comparison of strings.
//! @include example/string/orderable.cpp
//!
- //! 3. `Foldable`\n
+ //! 3. `Monoid`\n
+ //! Strings form a monoid under concatenation, with the neutral element
+ //! being the empty string.
+ //! @include example/string/monoid.cpp
+ //!
+ //! 4. `Foldable`\n
//! Folding a string is equivalent to folding the sequence of its
//! characters.
//! @include example/string/foldable.cpp
//!
- //! 4. `Iterable`\n
+ //! 5. `Iterable`\n
//! Iterating over a string is equivalent to iterating over the sequence
//! of its characters. Also note that `operator[]` can be used instead of
//! the `at` function.
//! @include example/string/iterable.cpp
//!
- //! 5. `Searchable`\n
+ //! 6. `Searchable`\n
//! Searching through a string is equivalent to searching through the
//! sequence of its characters.
//! @include example/string/searchable.cpp
//!
- //! 6. `Hashable`\n
+ //! 7. `Hashable`\n
//! The hash of a compile-time string is a type uniquely representing
//! that string.
//! @include example/string/hashable.cpp
@@ -82,10 +87,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! Conversion to `char const*`
//! ---------------------------
//! A `hana::string` can be converted to a `constexpr` null-delimited
- //! string of type `char const*` by using `to<char const*>`. This makes
- //! it easy to turn a compile-time string into a runtime string. However,
- //! note that this conversion is not an embedding, because `char const*`
- //! does not model the same concepts as `hana::string` does.
+ //! string of type `char const*` by using the `c_str()` method or
+ //! `hana::to<char const*>`. This makes it easy to turn a compile-time
+ //! string into a runtime string. However, note that this conversion is
+ //! not an embedding, because `char const*` does not model the same
+ //! concepts as `hana::string` does.
//! @include example/string/to.cpp
//!
//!
@@ -124,9 +130,16 @@ BOOST_HANA_NAMESPACE_BEGIN
template <typename X, typename Y>
friend constexpr auto operator>=(X&& x, Y&& y);
+ //! Performs concatenation; equivalent to `hana::plus`
+ template <typename X, typename Y>
+ friend constexpr auto operator+(X&& x, Y&& y);
+
//! Equivalent to `hana::at`
template <typename N>
constexpr decltype(auto) operator[](N&& n);
+
+ //! Returns a null-delimited C-style string.
+ static constexpr char const* c_str();
};
#else
template <char ...s>
diff --git a/boost/hana/fwd/type.hpp b/boost/hana/fwd/type.hpp
index b0a6aec20c..d3390cf5bd 100644
--- a/boost/hana/fwd/type.hpp
+++ b/boost/hana/fwd/type.hpp
@@ -122,7 +122,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! @relates hana::type
//!
//! @deprecated
- //! The semantics of `decltype_` are can be confusing, and `hana::typeid_`
+ //! The semantics of `decltype_` can be confusing, and `hana::typeid_`
//! should be preferred instead. `decltype_` may be removed in the next
//! major version of the library.
//!
@@ -396,7 +396,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! [1]: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1430
#ifdef BOOST_HANA_DOXYGEN_INVOKED
template <template <typename ...> class F>
- constexpr auto template_ = [](basic_type<T>-or-T ...) {
+ constexpr auto template_ = [](basic_type<T>...) {
return hana::type_c<F<T...>>;
};
#else
@@ -423,7 +423,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! @include example/type/metafunction.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
template <template <typename ...> class F>
- constexpr auto metafunction = [](basic_type<T>-or-T ...) {
+ constexpr auto metafunction = [](basic_type<T>...) {
return hana::type_c<typename F<T...>::type>;
};
#else
@@ -450,7 +450,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! @include example/type/metafunction_class.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
template <typename F>
- constexpr auto metafunction_class = [](basic_type<T>-or-T ...) {
+ constexpr auto metafunction_class = [](basic_type<T>...) {
return hana::type_c<typename F::template apply<T...>::type>;
};
#else
@@ -495,7 +495,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! @include example/type/integral.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto integral = [](auto f) {
- return [](basic_type<T>-or-T ...) {
+ return [](basic_type<T>...) {
return decltype(f)::apply<T...>::type{};
};
};
diff --git a/boost/hana/length.hpp b/boost/hana/length.hpp
index c7224df9bd..f8493a77c5 100644
--- a/boost/hana/length.hpp
+++ b/boost/hana/length.hpp
@@ -40,8 +40,8 @@ BOOST_HANA_NAMESPACE_BEGIN
namespace detail {
struct argn {
template <typename ...Xs>
- constexpr auto operator()(Xs const& ...) const
- { return hana::size_c<sizeof...(Xs)>; }
+ constexpr hana::size_t<sizeof...(Xs)> operator()(Xs const& ...) const
+ { return {}; }
};
}
diff --git a/boost/hana/map.hpp b/boost/hana/map.hpp
index 4aecb68482..3161d9b777 100644
--- a/boost/hana/map.hpp
+++ b/boost/hana/map.hpp
@@ -53,6 +53,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/value.hpp>
#include <cstddef>
+#include <type_traits>
#include <utility>
@@ -71,33 +72,39 @@ BOOST_HANA_NAMESPACE_BEGIN
// map
//////////////////////////////////////////////////////////////////////////
//! @cond
- template <typename HashTable, typename Storage>
- struct map
- : detail::searchable_operators<map<HashTable, Storage>>
- , detail::operators::adl<map<HashTable, Storage>>
- {
- using hash_table_type = HashTable;
- using storage_type = Storage;
-
- Storage storage;
-
- using hana_tag = map_tag;
-
- explicit constexpr map(Storage const& xs)
- : storage(xs)
- { }
-
- explicit constexpr map(Storage&& xs)
- : storage(static_cast<Storage&&>(xs))
- { }
-
- constexpr map() = default;
- constexpr map(map const& other) = default;
- constexpr map(map&& other) = default;
- };
- //! @endcond
-
namespace detail {
+ template <typename HashTable, typename Storage>
+ struct map_impl
+ : detail::searchable_operators<map_impl<HashTable, Storage>>
+ , detail::operators::adl<map_impl<HashTable, Storage>>
+ {
+ using hash_table_type = HashTable;
+ using storage_type = Storage;
+
+ Storage storage;
+
+ using hana_tag = map_tag;
+
+ template <typename ...P, typename = typename std::enable_if<
+ std::is_same<
+ Storage,
+ hana::basic_tuple<typename detail::decay<P>::type...>
+ >::value
+ >::type>
+ explicit constexpr map_impl(P&& ...pairs)
+ : storage{static_cast<P&&>(pairs)...}
+ { }
+
+ explicit constexpr map_impl(Storage&& xs)
+ : storage(static_cast<Storage&&>(xs))
+ { }
+
+ constexpr map_impl() = default;
+ constexpr map_impl(map_impl const& other) = default;
+ constexpr map_impl(map_impl&& other) = default;
+ };
+ //! @endcond
+
template <typename Storage>
struct KeyAtIndex {
template <std::size_t i>
@@ -117,12 +124,12 @@ BOOST_HANA_NAMESPACE_BEGIN
"hana::make_map(pairs...) requires all the 'pairs' to be Products");
static_assert(detail::fast_and<
- Comparable<decltype(hana::first(pairs))>::value...
+ hana::Comparable<decltype(hana::first(pairs))>::value...
>::value,
"hana::make_map(pairs...) requires all the keys to be Comparable");
static_assert(detail::fast_and<
- Constant<
+ hana::Constant<
decltype(hana::equal(hana::first(pairs), hana::first(pairs)))
>::value...
>::value,
@@ -144,9 +151,9 @@ BOOST_HANA_NAMESPACE_BEGIN
detail::KeyAtIndex<Storage>::template apply, sizeof...(Pairs)
>::type;
- return map<HashTable, Storage>(
+ return detail::map_impl<HashTable, Storage>{
hana::make_basic_tuple(static_cast<Pairs&&>(pairs)...)
- );
+ };
}
};
@@ -189,7 +196,7 @@ BOOST_HANA_NAMESPACE_BEGIN
using NewStorage = decltype(
hana::append(static_cast<Map&&>(map).storage, static_cast<Pair&&>(pair))
);
- return hana::map<NewHashTable, NewStorage>(
+ return detail::map_impl<NewHashTable, NewStorage>(
hana::append(static_cast<Map&&>(map).storage, static_cast<Pair&&>(pair))
);
}
diff --git a/boost/hana/string.hpp b/boost/hana/string.hpp
index 836a92be6a..a1b97d2cbb 100644
--- a/boost/hana/string.hpp
+++ b/boost/hana/string.hpp
@@ -32,7 +32,9 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/fwd/is_empty.hpp>
#include <boost/hana/fwd/length.hpp>
#include <boost/hana/fwd/less.hpp>
+#include <boost/hana/fwd/plus.hpp>
#include <boost/hana/fwd/unpack.hpp>
+#include <boost/hana/fwd/zero.hpp>
#include <boost/hana/if.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/optional.hpp>
@@ -48,11 +50,20 @@ BOOST_HANA_NAMESPACE_BEGIN
// string<>
//////////////////////////////////////////////////////////////////////////
//! @cond
+ namespace detail {
+ template <char ...s>
+ constexpr char const string_storage[sizeof...(s) + 1] = {s..., '\0'};
+ }
+
template <char ...s>
struct string
: detail::operators::adl<string<s...>>
, detail::iterable_operators<string<s...>>
- { };
+ {
+ static constexpr char const* c_str() {
+ return &detail::string_storage<s...>[0];
+ }
+ };
//! @endcond
template <char ...s>
@@ -132,16 +143,10 @@ BOOST_HANA_NAMESPACE_BEGIN
template <>
struct to_impl<char const*, string_tag> {
template <char ...c>
- static constexpr char const c_string[sizeof...(c) + 1] = {c..., '\0'};
-
- template <char ...c>
static constexpr char const* apply(string<c...> const&)
- { return c_string<c...>; }
+ { return string<c...>::c_str(); }
};
- template <char ...c>
- constexpr char const to_impl<char const*, string_tag>::c_string[sizeof...(c) + 1];
-
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////
@@ -175,6 +180,30 @@ BOOST_HANA_NAMESPACE_BEGIN
};
//////////////////////////////////////////////////////////////////////////
+ // Monoid
+ //////////////////////////////////////////////////////////////////////////
+ template <>
+ struct plus_impl<string_tag, string_tag> {
+ template <char ...s1, char ...s2>
+ static constexpr auto
+ apply(string<s1...> const&, string<s2...> const&) {
+ return string<s1..., s2...>{};
+ }
+ };
+
+ template <>
+ struct zero_impl<string_tag> {
+ static constexpr auto apply() {
+ return string<>{};
+ }
+ };
+
+ template <char ...s1, char ...s2>
+ constexpr auto operator+(string<s1...> const&, string<s2...> const&) {
+ return hana::string<s1..., s2...>{};
+ }
+
+ //////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////
template <>
diff --git a/boost/hana/version.hpp b/boost/hana/version.hpp
index b8481658bd..33b30eddfc 100644
--- a/boost/hana/version.hpp
+++ b/boost/hana/version.hpp
@@ -28,7 +28,7 @@ Distributed under the Boost Software License, Version 1.0.
//! @ingroup group-config
//! Macro expanding to the patch level of the library, i.e. the `z` in `x.y.z`.
-#define BOOST_HANA_PATCH_VERSION 1
+#define BOOST_HANA_PATCH_VERSION 2
//! @ingroup group-config
//! Macro expanding to the full version of the library, in hexadecimal