update boost on linux

This commit is contained in:
Bassem Girgis
2019-08-10 16:06:25 -05:00
parent 76ad52be58
commit 861b918727
5363 changed files with 483306 additions and 116507 deletions

View File

@@ -286,16 +286,35 @@ Distributed under the Boost Software License, Version 1.0.
// BOOST_HANA_CONSTEXPR_CHECK and BOOST_HANA_CONSTEXPR_CHECK_MSG
//////////////////////////////////////////////////////////////////////////////
//! @ingroup group-assertions
//! Equivalent to `BOOST_HANA_CONSTEXPR_ASSERT_MSG`, but not influenced by the
//! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. For internal use only.
#if defined(BOOST_HANA_DOXYGEN_INVOKED)
//! @ingroup group-assertions
//! Equivalent to `BOOST_HANA_CONSTEXPR_ASSERT_MSG`, but not influenced by
//! the `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro.
//! For internal use only.
# define BOOST_HANA_CONSTEXPR_CHECK_MSG(condition, message) implementation-defined
//! @ingroup group-assertions
//! Equivalent to `BOOST_HANA_CONSTEXPR_ASSERT`, but not influenced by the
//! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro.
//! For internal use only.
# define BOOST_HANA_CONSTEXPR_CHECK(...) implementation-defined
#elif defined(BOOST_HANA_CONFIG_HAS_CONSTEXPR_LAMBDA)
# define BOOST_HANA_CONSTEXPR_CHECK_MSG(condition, message) \
static_assert(condition, message) \
/**/
# define BOOST_HANA_CONSTEXPR_CHECK(...) \
static_assert((__VA_ARGS__), BOOST_HANA_PP_STRINGIZE(__VA_ARGS__)) \
/**/
#else
# define BOOST_HANA_CONSTEXPR_CHECK_MSG(condition, message) \
BOOST_HANA_RUNTIME_CHECK_MSG(condition, message) \
/**/
//! @ingroup group-assertions
//! Equivalent to `BOOST_HANA_CONSTEXPR_ASSERT`, but not influenced by the
//! `BOOST_HANA_CONFIG_DISABLE_ASSERTIONS` config macro. For internal use only.
# define BOOST_HANA_CONSTEXPR_CHECK(...) \
BOOST_HANA_CONSTEXPR_CHECK_MSG( \
(__VA_ARGS__), \
@@ -303,4 +322,6 @@ Distributed under the Boost Software License, Version 1.0.
) \
/**/
#endif
#endif // !BOOST_HANA_ASSERT_HPP

View File

@@ -3,6 +3,7 @@
Defines `boost::hana::at_key`.
@copyright Louis Dionne 2013-2017
@copyright Jason Rice 2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
@@ -24,6 +25,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/find_if.hpp>
#include <boost/hana/first.hpp>
#include <boost/hana/functional/on.hpp>
#include <boost/hana/index_if.hpp>
#include <boost/hana/length.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/second.hpp>
@@ -67,42 +69,16 @@ BOOST_HANA_NAMESPACE_BEGIN
return hana::equal(t, u);
}
};
//! @todo This causes an awful duplication of code with `find_if`.
template <typename Xs, typename Pred, std::size_t i, std::size_t N, bool Done>
struct advance_until;
template <typename Xs, typename Pred, std::size_t i, std::size_t N>
struct advance_until<Xs, Pred, i, N, false>
: advance_until<Xs, Pred, i + 1, N, static_cast<bool>(detail::decay<decltype(
std::declval<Pred>()(hana::at_c<i>(std::declval<Xs>()))
)>::type::value)>
{ };
template <typename Xs, typename Pred, std::size_t N>
struct advance_until<Xs, Pred, N, N, false> {
template <typename Ys>
static constexpr auto apply(Ys&&) = delete;
};
template <typename Xs, typename Pred, std::size_t i, std::size_t N>
struct advance_until<Xs, Pred, i, N, true> {
template <typename Ys>
static constexpr decltype(auto) apply(Ys&& ys) {
return hana::at_c<i - 1>(static_cast<Ys&&>(ys));
}
};
}
template <typename S>
struct at_key_impl<S, when<hana::Sequence<S>::value>> {
template <typename Xs, typename Key>
static constexpr decltype(auto) apply(Xs&& xs, Key const&) {
constexpr std::size_t N = decltype(hana::length(xs))::value;
using Pred = at_key_detail::equal_to<Key>;
return at_key_detail::advance_until<Xs&&, Pred, 0, N, false>::apply(
static_cast<Xs&&>(xs)
);
static constexpr decltype(auto) apply(Xs&& xs, Key const& key) {
using Result = decltype(hana::index_if(
static_cast<Xs&&>(xs), at_key_detail::equal_to<Key>{key}));
return hana::at(static_cast<Xs&&>(xs), Result{}.value());
}
};

View File

@@ -21,15 +21,12 @@ Distributed under the Boost Software License, Version 1.0.
#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/integral_constant.hpp>
#include <boost/hana/fwd/is_empty.hpp>
#include <boost/hana/fwd/length.hpp>
#include <boost/hana/fwd/transform.hpp>
#include <boost/hana/fwd/unpack.hpp>
#if 0 //! @todo Until we strip down headers, this includes too much
#include <boost/hana/fwd/integral_constant.hpp>
#include <boost/hana/fwd/length.hpp>
#endif
#include <cstddef>
#include <type_traits>
#include <utility>
@@ -244,7 +241,6 @@ BOOST_HANA_NAMESPACE_BEGIN
}
};
#if 0
//////////////////////////////////////////////////////////////////////////
// length
//////////////////////////////////////////////////////////////////////////
@@ -252,10 +248,9 @@ BOOST_HANA_NAMESPACE_BEGIN
struct length_impl<basic_tuple_tag> {
template <typename ...Xn>
static constexpr auto apply(basic_tuple<Xn...> const&) {
return hana::size_c<sizeof...(Xn)>;
return hana::size_t<sizeof...(Xn)>{};
}
};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_BASIC_TUPLE_HPP

View File

@@ -182,8 +182,10 @@ BOOST_HANA_NAMESPACE_BEGIN
for (std::size_t i = 0; i < N - offset; ++i) {
char c = arr[N - 1 - i];
number += to_int(c) * multiplier;
multiplier *= base;
if (c != '\'') { // skip digit separators
number += to_int(c) * multiplier;
multiplier *= base;
}
}
return number;

View File

@@ -49,7 +49,7 @@ BOOST_HANA_NAMESPACE_BEGIN
template <std::size_t ...Lengths>
struct cartesian_product_indices {
static constexpr std::size_t total_length() {
std::size_t lengths[] = {Lengths...};
std::size_t lengths[sizeof...(Lengths)] = {Lengths...};
std::size_t r = 1;
for (std::size_t len: lengths)
r *= len;
@@ -59,7 +59,7 @@ BOOST_HANA_NAMESPACE_BEGIN
static constexpr std::size_t length = total_length();
static constexpr auto indices_of(std::size_t i) {
constexpr std::size_t lengths[] = {Lengths...};
constexpr std::size_t lengths[sizeof...(Lengths)] = {Lengths...};
constexpr std::size_t n = sizeof...(Lengths);
detail::array<std::size_t, n> result{};
for (std::size_t j = n; j--;) {

View File

@@ -124,26 +124,26 @@ Distributed under the Boost Software License, Version 1.0.
// Caveats and other compiler-dependent options
//////////////////////////////////////////////////////////////////////////////
// BOOST_HANA_CONFIG_HAS_CONSTEXPR_LAMBDA enables some constructs requiring
// `constexpr` lambdas, which are not in the language (yet).
// Currently always disabled.
// `BOOST_HANA_CONFIG_HAS_CONSTEXPR_LAMBDA` enables some constructs requiring
// `constexpr` lambdas, which are in the language starting with C++17.
//
// BOOST_HANA_CONSTEXPR_LAMBDA expands to `constexpr` if constexpr lambdas
// Always disabled for now because Clang only has partial support for them
// (captureless lambdas only).
#if defined(__cplusplus) && __cplusplus > 201402L
# define BOOST_HANA_CONSTEXPR_STATELESS_LAMBDA constexpr
// # define BOOST_HANA_CONFIG_HAS_CONSTEXPR_LAMBDA
#else
# define BOOST_HANA_CONSTEXPR_STATELESS_LAMBDA /* nothing */
#endif
// `BOOST_HANA_CONSTEXPR_LAMBDA` expands to `constexpr` if constexpr lambdas
// are supported and to nothing otherwise.
#if 0
# define BOOST_HANA_CONFIG_HAS_CONSTEXPR_LAMBDA
#if defined(BOOST_HANA_CONFIG_HAS_CONSTEXPR_LAMBDA)
# define BOOST_HANA_CONSTEXPR_LAMBDA constexpr
#else
# define BOOST_HANA_CONSTEXPR_LAMBDA /* nothing */
#endif
// The std::tuple adapter is broken on libc++ prior to the one shipped
// with Clang 3.7.0.
#if defined(BOOST_HANA_CONFIG_LIBCPP) && \
BOOST_HANA_CONFIG_LIBCPP < BOOST_HANA_CONFIG_VERSION(1, 0, 101)
# define BOOST_HANA_CONFIG_HAS_NO_STD_TUPLE_ADAPTER
#endif
// There's a bug in std::tuple_cat in libc++ right now.
// See http://llvm.org/bugs/show_bug.cgi?id=22806.
#if defined(BOOST_HANA_CONFIG_LIBCPP)

View File

@@ -39,27 +39,29 @@ BOOST_HANA_NAMESPACE_BEGIN
namespace convert_detail {
struct no_conversion { };
template <typename ...>
struct is_valid { static constexpr bool value = true; };
}
template <typename To, typename From, typename = void>
struct maybe_static_cast : no_conversion {
template <typename X>
static constexpr auto apply(X const&) {
static_assert(detail::wrong<to_impl<To, From>, X>{},
"no conversion is available between the provided types");
}
};
template <typename To, typename From>
struct maybe_static_cast<To, From, decltype((void)
static_cast<To>(std::declval<From>())
)> {
template <typename X>
static constexpr To apply(X&& x)
{ return static_cast<To>(static_cast<X&&>(x)); }
};
} // end namespace convert_detail
template <typename To, typename From, bool condition>
struct to_impl<To, From, when<condition>> : convert_detail::no_conversion {
template <typename X>
static constexpr auto apply(X const&) {
static_assert(detail::wrong<to_impl<To, From>, X>{},
"no conversion is available between the provided types");
}
};
template <typename To, typename From>
struct to_impl<To, From, when<convert_detail::is_valid<
decltype(static_cast<To>(std::declval<From>()))
>::value>> {
template <typename X>
static constexpr To apply(X&& x)
{ return static_cast<To>(static_cast<X&&>(x)); }
};
struct to_impl<To, From, when<condition>>
: convert_detail::maybe_static_cast<To, From>
{ };
template <typename To>
struct to_impl<To, To> : embedding<> {

View File

@@ -3,6 +3,7 @@
Defines `boost::hana::detail::index_if`.
@copyright Louis Dionne 2013-2017
@copyright Jason Rice 2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
@@ -11,61 +12,44 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_HANA_DETAIL_INDEX_IF_HPP
#include <boost/hana/config.hpp>
#include <boost/hana/core/when.hpp>
#include <boost/hana/detail/decay.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/optional.hpp>
#include <cstddef>
#include <utility>
BOOST_HANA_NAMESPACE_BEGIN namespace detail {
template <typename ...T>
struct pack {
static constexpr std::size_t length = sizeof...(T);
template <std::size_t i, std::size_t N, bool Done>
struct index_if_helper;
template <std::size_t i, std::size_t N>
struct index_if_helper<i, N, false> {
template <typename Pred, typename X1, typename ...Xs>
using f = typename index_if_helper<i + 1, N,
static_cast<bool>(detail::decay<decltype(
std::declval<Pred>()(std::declval<X1>()))>::type::value)
>::template f<Pred, Xs...>;
};
template <typename T>
struct make_pack;
template <template <typename...> class Template, typename ...T>
struct make_pack<Template<T...>> {
using type = pack<T...>;
template <std::size_t N>
struct index_if_helper<N, N, false> {
template <typename ...>
using f = hana::optional<>;
};
template <typename T> struct make_pack<T const> : make_pack<T> { };
template <typename T> struct make_pack<T&> : make_pack<T> { };
template <typename T> struct make_pack<T&&> : make_pack<T> { };
//! @ingroup group-details
//! Returns the index of the first element of the `pack<>` that satisfies
//! the predicate, or the size of the pack if there is no such element.
//!
//! @note
//! The predicate must return an `IntegralConstant` that can be explicitly
//! converted to `bool`.
template <typename Pred, typename Ts, typename = when<true>>
struct index_if;
//! @cond
template <typename Pred, typename T, typename ...Ts>
struct index_if<Pred, pack<T, Ts...>, when<static_cast<bool>(decltype(
std::declval<Pred>()(std::declval<T>())
)::value)>> {
static constexpr std::size_t value = 0;
template <std::size_t i, std::size_t N>
struct index_if_helper<i, N, true> {
template <typename ...>
using f = hana::optional<hana::size_t<i - 1>>;
};
template <typename Pred, typename T, typename ...Ts>
struct index_if<Pred, pack<T, Ts...>, when<!static_cast<bool>(decltype(
std::declval<Pred>()(std::declval<T>())
)::value)>> {
static constexpr std::size_t value = 1 + index_if<Pred, pack<Ts...>>::value;
template <typename Pred, typename ...Xs>
struct index_if {
using type = typename index_if_helper<0, sizeof...(Xs), false>
::template f<Pred, Xs...>;
};
template <typename Pred>
struct index_if<Pred, pack<>> {
static constexpr std::size_t value = 0;
};
//! @endcond
} BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_DETAIL_INDEX_IF_HPP

View File

@@ -10,16 +10,6 @@ Distributed under the Boost Software License, Version 1.0.
#ifndef BOOST_HANA_DETAIL_PREPROCESSOR_HPP
#define BOOST_HANA_DETAIL_PREPROCESSOR_HPP
//! @ingroup group-details
//! Macro expanding to the number of arguments it is passed.
//!
//! Specifically, `BOOST_HANA_PP_NARG(x1, ..., xn)` expands to `n`.
//! It is undefined behavior if `n > 64` or if `n == 0`.
#define BOOST_HANA_PP_NARG(...) \
BOOST_HANA_PP_NARG_IMPL(__VA_ARGS__, 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
#define BOOST_HANA_PP_NARG_IMPL(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, N, ...) N
//! @ingroup group-details
//! Expands to the concatenation of its two arguments.
#define BOOST_HANA_PP_CONCAT(x, y) BOOST_HANA_PP_CONCAT_PRIMITIVE(x, y)
@@ -30,68 +20,6 @@ Distributed under the Boost Software License, Version 1.0.
#define BOOST_HANA_PP_STRINGIZE(...) BOOST_HANA_PP_STRINGIZE_PRIMITIVE(__VA_ARGS__)
#define BOOST_HANA_PP_STRINGIZE_PRIMITIVE(...) #__VA_ARGS__
//! @ingroup group-details
//! Expands to its last argument.
//!
//! This macro can be passed up to 20 arguments.
#define BOOST_HANA_PP_BACK(...) \
BOOST_HANA_PP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)
#define BOOST_HANA_PP_BACK_IMPL(N, ...) \
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_BACK_IMPL_, N)(__VA_ARGS__)
#define BOOST_HANA_PP_BACK_IMPL_1(e0) e0
#define BOOST_HANA_PP_BACK_IMPL_2(e0, e1) e1
#define BOOST_HANA_PP_BACK_IMPL_3(e0, e1, e2) e2
#define BOOST_HANA_PP_BACK_IMPL_4(e0, e1, e2, e3) e3
#define BOOST_HANA_PP_BACK_IMPL_5(e0, e1, e2, e3, e4) e4
#define BOOST_HANA_PP_BACK_IMPL_6(e0, e1, e2, e3, e4, e5) e5
#define BOOST_HANA_PP_BACK_IMPL_7(e0, e1, e2, e3, e4, e5, e6) e6
#define BOOST_HANA_PP_BACK_IMPL_8(e0, e1, e2, e3, e4, e5, e6, e7) e7
#define BOOST_HANA_PP_BACK_IMPL_9(e0, e1, e2, e3, e4, e5, e6, e7, e8) e8
#define BOOST_HANA_PP_BACK_IMPL_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) e9
#define BOOST_HANA_PP_BACK_IMPL_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) e10
#define BOOST_HANA_PP_BACK_IMPL_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) e11
#define BOOST_HANA_PP_BACK_IMPL_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12) e12
#define BOOST_HANA_PP_BACK_IMPL_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13) e13
#define BOOST_HANA_PP_BACK_IMPL_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14) e14
#define BOOST_HANA_PP_BACK_IMPL_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15) e15
#define BOOST_HANA_PP_BACK_IMPL_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16) e16
#define BOOST_HANA_PP_BACK_IMPL_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17) e17
#define BOOST_HANA_PP_BACK_IMPL_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18) e18
#define BOOST_HANA_PP_BACK_IMPL_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19) e19
//! @ingroup group-details
//! Expands to all of its arguments, except for the last one.
//!
//! This macro can be given up to 20 arguments.
#define BOOST_HANA_PP_DROP_BACK(...) \
BOOST_HANA_PP_DROP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)
#define BOOST_HANA_PP_DROP_BACK_IMPL(N, ...) \
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_DROP_BACK_IMPL_, N)(__VA_ARGS__)
#define BOOST_HANA_PP_DROP_BACK_IMPL_1(e0)
#define BOOST_HANA_PP_DROP_BACK_IMPL_2(e0, e1) e0
#define BOOST_HANA_PP_DROP_BACK_IMPL_3(e0, e1, e2) e0, e1
#define BOOST_HANA_PP_DROP_BACK_IMPL_4(e0, e1, e2, e3) e0, e1, e2
#define BOOST_HANA_PP_DROP_BACK_IMPL_5(e0, e1, e2, e3, e4) e0, e1, e2, e3
#define BOOST_HANA_PP_DROP_BACK_IMPL_6(e0, e1, e2, e3, e4, e5) e0, e1, e2, e3, e4
#define BOOST_HANA_PP_DROP_BACK_IMPL_7(e0, e1, e2, e3, e4, e5, e6) e0, e1, e2, e3, e4, e5
#define BOOST_HANA_PP_DROP_BACK_IMPL_8(e0, e1, e2, e3, e4, e5, e6, e7) e0, e1, e2, e3, e4, e5, e6
#define BOOST_HANA_PP_DROP_BACK_IMPL_9(e0, e1, e2, e3, e4, e5, e6, e7, e8) e0, e1, e2, e3, e4, e5, e6, e7
#define BOOST_HANA_PP_DROP_BACK_IMPL_10(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9) e0, e1, e2, e3, e4, e5, e6, e7, e8
#define BOOST_HANA_PP_DROP_BACK_IMPL_11(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9
#define BOOST_HANA_PP_DROP_BACK_IMPL_12(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10
#define BOOST_HANA_PP_DROP_BACK_IMPL_13(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11
#define BOOST_HANA_PP_DROP_BACK_IMPL_14(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12
#define BOOST_HANA_PP_DROP_BACK_IMPL_15(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13
#define BOOST_HANA_PP_DROP_BACK_IMPL_16(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14
#define BOOST_HANA_PP_DROP_BACK_IMPL_17(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15
#define BOOST_HANA_PP_DROP_BACK_IMPL_18(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16
#define BOOST_HANA_PP_DROP_BACK_IMPL_19(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17
#define BOOST_HANA_PP_DROP_BACK_IMPL_20(e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19) e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18
//! @ingroup group-details
//! Expands to its first argument.
#define BOOST_HANA_PP_FRONT(...) BOOST_HANA_PP_FRONT_IMPL(__VA_ARGS__, )

View File

@@ -1,185 +0,0 @@
<%#
This is an ERB [1] template file used to generate the
<boost/hana/detail/struct_macros.hpp> header. The maximum
number of members that can be handled by the macros can
be controlled with the 'MAX_NUMBER_OF_MEMBERS' variable,
which can be set when calling ERB to generate the header:
export MAX_NUMBER_OF_MEMBERS=55; erb struct_macros.erb.hpp
'MAX_NUMBER_OF_MEMBERS' must be <= 62, otherwise an error is triggered.
In case 'MAX_NUMBER_OF_MEMBERS' is not specified, it defaults to 40.
[1]: http://en.wikipedia.org/wiki/ERuby
%>
<%
MAX_NUMBER_OF_MEMBERS = (ENV["MAX_NUMBER_OF_MEMBERS"] || 40).to_i
raise "MAX_NUMBER_OF_MEMBERS must be <= 62" if MAX_NUMBER_OF_MEMBERS > 62
%>
/*!
@file
Defines the `BOOST_HANA_DEFINE_STRUCT`, `BOOST_HANA_ADAPT_STRUCT`, and
`BOOST_HANA_ADAPT_ADT` macros.
@copyright Louis Dionne 2013-2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//////////////////////////////////////////////////////////////////////////////
// THIS FILE IS GENERATED FROM THE <boost/hana/detail/struct_macros.erb.hpp>
// ERB TEMPLATE. DO NOT EDIT THIS FILE DIRECTLY.
//
// THE ERB TEMPLATE CONTAINS INFORMATION ABOUT HOW TO REGENERATE THIS FILE.
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_HANA_DETAIL_STRUCT_MACROS_HPP
#define BOOST_HANA_DETAIL_STRUCT_MACROS_HPP
#include <boost/hana/config.hpp>
#include <boost/hana/detail/preprocessor.hpp>
#include <boost/hana/pair.hpp>
#include <boost/hana/string.hpp>
#include <boost/hana/tuple.hpp>
#include <cstddef>
#include <utility>
BOOST_HANA_NAMESPACE_BEGIN namespace struct_detail {
template <typename Memptr, Memptr ptr>
struct member_ptr {
template <typename T>
constexpr decltype(auto) operator()(T&& t) const
{ return static_cast<T&&>(t).*ptr; }
};
constexpr std::size_t strlen(char const* s) {
std::size_t n = 0;
while (*s++ != '\0')
++n;
return n;
}
template <std::size_t n, typename Names, std::size_t ...i>
constexpr auto prepare_member_name_impl(std::index_sequence<i...>) {
return hana::string_c<hana::at_c<n>(Names::get())[i]...>;
}
template <std::size_t n, typename Names>
constexpr auto prepare_member_name() {
constexpr std::size_t len = strlen(hana::at_c<n>(Names::get()));
return prepare_member_name_impl<n, Names>(std::make_index_sequence<len>{});
}
} BOOST_HANA_NAMESPACE_END
//////////////////////////////////////////////////////////////////////////////
// BOOST_HANA_ADAPT_STRUCT
//////////////////////////////////////////////////////////////////////////////
template <typename ...>
struct BOOST_HANA_ADAPT_STRUCT_must_be_called_in_the_global_namespace;
#define BOOST_HANA_ADAPT_STRUCT(...) \
template <> \
struct BOOST_HANA_ADAPT_STRUCT_must_be_called_in_the_global_namespace<>; \
BOOST_HANA_ADAPT_STRUCT_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)\
static_assert(true, "force the usage of a trailing semicolon") \
/**/
#define BOOST_HANA_ADAPT_STRUCT_IMPL(N, ...) \
BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_STRUCT_IMPL_, N)(__VA_ARGS__)
<% (0..MAX_NUMBER_OF_MEMBERS).each do |n| %>
#define BOOST_HANA_ADAPT_STRUCT_IMPL_<%= n+1 %>(TYPE <%= (1..n).map { |i| ", m#{i}" }.join %>) \
namespace boost { namespace hana { \
template <> \
struct accessors_impl<TYPE> { \
static constexpr auto apply() { \
struct member_names { \
static constexpr auto get() { \
return ::boost::hana::make_tuple( \
<%= (1..n).map { |i| "BOOST_HANA_PP_STRINGIZE(m#{i})" }.join(', ') %> \
); \
} \
}; \
return ::boost::hana::make_tuple( \
<%= (1..n).map { |i| "::boost::hana::make_pair(::boost::hana::struct_detail::prepare_member_name<#{i-1}, member_names>(), ::boost::hana::struct_detail::member_ptr<decltype(&TYPE::m#{i}), &TYPE::m#{i}>{})" }.join(', ') %>\
); \
} \
}; \
}} \
/**/
<% end %>
//////////////////////////////////////////////////////////////////////////////
// BOOST_HANA_ADAPT_ADT
//////////////////////////////////////////////////////////////////////////////
template <typename ...>
struct BOOST_HANA_ADAPT_ADT_must_be_called_in_the_global_namespace;
#define BOOST_HANA_ADAPT_ADT(...) \
template <> \
struct BOOST_HANA_ADAPT_ADT_must_be_called_in_the_global_namespace<>; \
BOOST_HANA_ADAPT_ADT_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__) \
static_assert(true, "force the usage of a trailing semicolon") \
/**/
#define BOOST_HANA_ADAPT_ADT_IMPL(N, ...) \
BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_ADT_IMPL_, N)(__VA_ARGS__)
<% (0..MAX_NUMBER_OF_MEMBERS).each do |n| %>
#define BOOST_HANA_ADAPT_ADT_IMPL_<%= n+1 %>(TYPE <%= (1..n).map { |i| ", m#{i}" }.join %>) \
namespace boost { namespace hana { \
template <> \
struct accessors_impl<TYPE> { \
template <typename ...> \
static constexpr auto apply() { \
struct member_names { \
static constexpr auto get() { \
return ::boost::hana::make_tuple( \
<%= (1..n).map { |i| "BOOST_HANA_PP_STRINGIZE(BOOST_HANA_PP_FRONT m#{i})" }.join(', ') %>\
); \
} \
}; \
return ::boost::hana::make_tuple( \
<%= (1..n).map { |i| "::boost::hana::make_pair(::boost::hana::struct_detail::prepare_member_name<#{i-1}, member_names>(), BOOST_HANA_PP_DROP_FRONT m#{i})" }.join(', ') %>\
); \
} \
}; \
}} \
/**/
<% end %>
//////////////////////////////////////////////////////////////////////////////
// BOOST_HANA_DEFINE_STRUCT
//////////////////////////////////////////////////////////////////////////////
#define BOOST_HANA_DEFINE_STRUCT(...) \
BOOST_HANA_DEFINE_STRUCT_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)
#define BOOST_HANA_DEFINE_STRUCT_IMPL(N, ...) \
BOOST_HANA_PP_CONCAT(BOOST_HANA_DEFINE_STRUCT_IMPL_, N)(__VA_ARGS__)
<% (0..MAX_NUMBER_OF_MEMBERS).each do |n| %>
#define BOOST_HANA_DEFINE_STRUCT_IMPL_<%= n+1 %>(TYPE <%= (1..n).map { |i| ", m#{i}" }.join %>) \
<%= (1..n).map { |i| "BOOST_HANA_PP_DROP_BACK m#{i} BOOST_HANA_PP_BACK m#{i};" }.join(' ') %> \
\
struct hana_accessors_impl { \
static constexpr auto apply() { \
struct member_names { \
static constexpr auto get() { \
return ::boost::hana::make_tuple( \
<%= (1..n).map { |i| "BOOST_HANA_PP_STRINGIZE(BOOST_HANA_PP_BACK m#{i})" }.join(', ') %>\
); \
} \
}; \
return ::boost::hana::make_tuple( \
<%= (1..n).map { |i| "::boost::hana::make_pair(::boost::hana::struct_detail::prepare_member_name<#{i-1}, member_names>(), ::boost::hana::struct_detail::member_ptr<decltype(&TYPE::BOOST_HANA_PP_BACK m#{i}), &TYPE::BOOST_HANA_PP_BACK m#{i}>{})" }.join(', ') %>\
); \
} \
} \
/**/
<% end %>
#endif // !BOOST_HANA_DETAIL_STRUCT_MACROS_HPP

File diff suppressed because one or more lines are too long

View File

@@ -25,7 +25,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail {
template <std::size_t ...Lengths>
struct flatten_indices {
// avoid empty arrays by appending 0 to `lengths`
static constexpr std::size_t lengths[] = {Lengths..., 0};
static constexpr std::size_t lengths[sizeof...(Lengths) + 1] = {Lengths..., 0};
static constexpr auto flat_length =
detail::accumulate(lengths, lengths + sizeof...(Lengths), 0);

View File

@@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
//! @cond
template <unsigned int n, typename = when<true>>
struct foldl1_impl;
@@ -195,6 +196,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
, static_cast<Xn&&>(xn)...);
}
};
//! @endcond
struct foldl1_t {
template <typename F, typename X1, typename ...Xn>

View File

@@ -15,6 +15,7 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
//! @cond
template <unsigned int n, typename = when<true>>
struct foldr1_impl;
@@ -181,6 +182,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail { namespace variadic {
foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X56&&>(x56), static_cast<Xn&&>(xn)...))))))))))))))))))))))))))))))))))))))))))))))))))))))));
}
};
//! @endcond
struct foldr1_t {
template <typename F, typename X1, typename ...Xn>

View File

@@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/dispatch.hpp>
#include <boost/hana/erase_key.hpp>
BOOST_HANA_NAMESPACE_BEGIN

View File

@@ -20,21 +20,21 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename M>
struct empty_t {
constexpr auto empty_t<M>::operator()() const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::MonadPlus<M>::value,
"hana::empty<M>() requires 'M' to be a MonadPlus");
#endif
constexpr auto operator()() const {
using Empty = BOOST_HANA_DISPATCH_IF(empty_impl<M>,
hana::MonadPlus<M>::value
);
using Empty = BOOST_HANA_DISPATCH_IF(empty_impl<M>,
hana::MonadPlus<M>::value
);
return Empty::apply();
}
};
return Empty::apply();
}
//! @endcond
template <typename M, bool condition>
struct empty_impl<M, when<condition>> : default_ {

View File

@@ -99,7 +99,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace experimental {
namespace print_detail {
std::string strip_type_junk(std::string const& str) {
return std::regex_replace(str, std::regex("^([a-z_]+::)*([a-z_]*)_t<"), "$2<");
return std::regex_replace(str, std::regex("(?:struct )?([a-z_]+::)*([a-z_]*)_t<((?:struct )?[a-z:<>_]*)>"), "$2<$3>");
}
}

View File

@@ -16,6 +16,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/detail/decay.hpp>
#include <boost/hana/fold_left.hpp>
#include <boost/hana/functional/compose.hpp>
#include <boost/hana/functional/on.hpp>
#include <boost/hana/fwd/ap.hpp>
#include <boost/hana/fwd/concat.hpp>
#include <boost/hana/fwd/drop_front.hpp>

View File

@@ -99,9 +99,25 @@ BOOST_HANA_NAMESPACE_BEGIN
using vector_tag = ::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type;
}}}
namespace mpl_detail {
// When `BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES` is not defined (e.g. on
// MSVC), different MPL sequences (like vector0 and vector1) have different
// tags, so we need to take that into account when we compare them.
#ifndef BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES
template <typename T1, typename T2>
struct is_same_mpl_vector_tag : std::false_type { };
template <template <long> class Tag, long x, long y>
struct is_same_mpl_vector_tag<Tag<x>, Tag<y>> : std::true_type { };
#else
template <typename T1, typename T2>
struct is_same_mpl_vector_tag : std::is_same<T1, T2> { };
#endif
}
template <typename T>
struct tag_of<T, when<
std::is_same<
mpl_detail::is_same_mpl_vector_tag<
typename ::boost::mpl::sequence_tag<T>::type,
::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type
>::value

View File

@@ -14,17 +14,12 @@ Distributed under the Boost Software License, Version 1.0.
//! @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/tuple.hpp>
#include <boost/hana/ext/std/vector.hpp>
#endif // !BOOST_HANA_EXT_STD_HPP

View File

@@ -149,13 +149,21 @@ BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
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);
// This logic is more complex than it needs to be because we can't
// use `.begin()` and `.end()`, which are not constexpr in C++14,
// and because `&arr[0]` is UB when the array is empty.
if (xs.empty()) {
return !ys.empty();
} else {
if (ys.empty()) {
return false;
} else {
return detail::lexicographical_compare(&xs[0], &xs[0] + n,
&ys[0], &ys[0] + m);
}
}
}
};
BOOST_HANA_NAMESPACE_END

View File

@@ -31,13 +31,6 @@ Distributed under the Boost Software License, Version 1.0.
#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

View File

@@ -3,6 +3,7 @@
Defines `boost::hana::find_if`.
@copyright Louis Dionne 2013-2017
@copyright Jason Rice 2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
@@ -17,19 +18,12 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/bool.hpp>
#include <boost/hana/concept/iterable.hpp>
#include <boost/hana/concept/searchable.hpp>
#include <boost/hana/concept/sequence.hpp>
#include <boost/hana/concept/struct.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/core/dispatch.hpp>
#include <boost/hana/detail/decay.hpp>
#include <boost/hana/drop_while.hpp>
#include <boost/hana/first.hpp>
#include <boost/hana/front.hpp>
#include <boost/hana/functional/compose.hpp>
#include <boost/hana/is_empty.hpp>
#include <boost/hana/length.hpp>
#include <boost/hana/not.hpp>
#include <boost/hana/optional.hpp>
#include <boost/hana/index_if.hpp>
#include <boost/hana/second.hpp>
#include <boost/hana/transform.hpp>
@@ -62,68 +56,26 @@ BOOST_HANA_NAMESPACE_BEGIN
};
namespace detail {
template <typename Xs, typename Pred, std::size_t i, std::size_t N, bool Done>
struct advance_until;
template <typename Xs>
struct partial_at {
Xs const& xs;
template <typename Xs, typename Pred, std::size_t i, std::size_t N>
struct advance_until<Xs, Pred, i, N, false>
: advance_until<Xs, Pred, i + 1, N, static_cast<bool>(detail::decay<decltype(
std::declval<Pred>()(hana::at_c<i>(std::declval<Xs>()))
)>::type::value)>
{ };
template <typename Xs, typename Pred, std::size_t N>
struct advance_until<Xs, Pred, N, N, false> {
template <typename Ys>
static constexpr auto apply(Ys&&) {
return hana::nothing;
}
};
template <typename Xs, typename Pred, std::size_t i, std::size_t N>
struct advance_until<Xs, Pred, i, N, true> {
template <typename Ys>
static constexpr auto apply(Ys&& ys) {
return hana::just(hana::at_c<i - 1>(static_cast<Ys&&>(ys)));
template <typename I>
constexpr decltype(auto) operator()(I i) const {
return hana::at(xs, i);
}
};
}
template <typename S>
struct find_if_impl<S, when<Sequence<S>::value>> {
template <typename Xs, typename Pred>
static constexpr auto apply(Xs&& xs, Pred&&) {
constexpr std::size_t N = decltype(hana::length(xs))::value;
return detail::advance_until<Xs&&, Pred&&, 0, N, false>::apply(
static_cast<Xs&&>(xs)
);
}
};
template <typename It>
struct find_if_impl<It, when<hana::Iterable<It>::value && !Sequence<It>::value>> {
template <typename Xs, typename Pred>
static constexpr auto find_if_helper(Xs&& xs, Pred&& pred, hana::true_) {
return hana::just(hana::front(
hana::drop_while(static_cast<Xs&&>(xs),
hana::compose(hana::not_, static_cast<Pred&&>(pred)))
));
}
template <typename Xs, typename Pred>
static constexpr auto find_if_helper(Xs&&, Pred&&, hana::false_) {
return hana::nothing;
}
template <typename Tag>
struct find_if_impl<Tag, when<Iterable<Tag>::value>> {
template <typename Xs, typename Pred>
static constexpr auto apply(Xs&& xs, Pred&& pred) {
constexpr bool found = !decltype(
hana::is_empty(hana::drop_while(static_cast<Xs&&>(xs),
hana::compose(hana::not_, static_cast<Pred&&>(pred))))
)::value;
return find_if_impl::find_if_helper(static_cast<Xs&&>(xs),
static_cast<Pred&&>(pred),
hana::bool_<found>{});
using Result = decltype(hana::index_if(
static_cast<Xs&&>(xs), static_cast<Pred&&>(pred)));
return hana::transform(Result{},
detail::partial_at<std::decay_t<Xs>>{static_cast<Xs&&>(xs)});
}
};

View File

@@ -31,7 +31,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! ---------
//! Given a `Functor` `F` and a `Logical` `Bool`, the signature is
//! \f$
//! \mathtt{adjust_if} : F(T) \times (T \to Bool) \times (T \to T) \to F(T)
//! \mathtt{adjust\_if} : F(T) \times (T \to Bool) \times (T \to T) \to F(T)
//! \f$
//!
//! @param xs

View File

@@ -22,6 +22,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! `std::tuple`, `basic_tuple` provides the strict minimum required to
//! implement a closure with maximum compile-time efficiency.
//!
//! @note
//! When you use a container, remember not to make assumptions about its
//! representation, unless the documentation gives you those guarantees.
//! More details [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
//! ----------------

View File

@@ -57,7 +57,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! std::is_same<
//! typename fusion::traits::tag_of<T>::type,
//! fusion::traits::tag_of<fusion::vector<>>::type
//! >{}
//! >::value
//! >> {
//! using type = BoostFusionVector;
//! };

View File

@@ -15,50 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! Returns the set-theoretic difference of two sets.
//! @relates hana::set
//!
//! Given two sets `xs` and `ys`, `difference(xs, ys)` is a new set
//! containing all the elements of `xs` that are _not_ contained in `ys`.
//! For any object `x`, the following holds:
//! @code
//! x ^in^ difference(xs, ys) if and only if x ^in^ xs && !(x ^in^ ys)
//! @endcode
//!
//!
//! @note
//! This operation is not commutative, i.e. `difference(xs, ys)` is not
//! necessarily the same as `difference(ys, xs)`. Indeed, consider the
//! case where `xs` is empty and `ys` isn't. Then, `difference(xs, ys)`
//! is empty but `difference(ys, xs)` is equal to `ys`. For the symmetric
//! version of this operation, see `symmetric_difference`.
//!
//!
//! @param xs
//! A set to remove values from.
//!
//! @param ys
//! The set whose values are removed from `xs`.
//!
//!
//! Example
//! -------
//! @include example/difference.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto difference = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#else
// Note: This function is documented per datatype/concept only.
//! @cond
template <typename S, typename = void>
struct difference_impl : difference_impl<S, when<true>> { };
//! @endcond
struct difference_t {
template <typename Xs, typename Ys>
constexpr auto operator()(Xs&& xs, Ys&& ys) const;
constexpr auto operator()(Xs&&, Ys&&) const;
};
constexpr difference_t difference{};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_DIFFERENCE_HPP

View File

@@ -41,7 +41,9 @@ BOOST_HANA_NAMESPACE_BEGIN
struct empty_impl : empty_impl<M, when<true>> { };
template <typename M>
struct empty_t;
struct empty_t {
constexpr auto operator()() const;
};
template <typename M>
constexpr empty_t<M> empty{};

View File

@@ -0,0 +1,60 @@
/*!
@file
Forward declares `boost::hana::index_if`.
@copyright Louis Dionne 2013-2017
@copyright Jason Rice 2017
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_FWD_INDEX_IF_HPP
#define BOOST_HANA_FWD_INDEX_IF_HPP
#include <boost/hana/config.hpp>
#include <boost/hana/core/when.hpp>
BOOST_HANA_NAMESPACE_BEGIN
//! Finds the value associated to the first key satisfying a predicate.
//! @ingroup group-Iterable
//!
//! Given an `Iterable` structure `xs` and a predicate `pred`,
//! `index_if(xs, pred)` returns a `hana::optional` containing an `IntegralConstant`
//! of the index of the first element that satisfies the predicate or nothing
//! if no element satisfies the predicate.
//!
//!
//! @param xs
//! The structure to be searched.
//!
//! @param predicate
//! A function called as `predicate(x)`, where `x` is an element of the
//! `Iterable` structure and returning whether `x` is the element being
//! searched for. In the current version of the library, the predicate
//! has to return an `IntegralConstant` holding a value that can be
//! converted to `bool`.
//!
//!
//! Example
//! -------
//! @include example/index_if.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto index_if = [](auto&& xs, auto&& predicate) {
return tag-dispatched;
};
#else
template <typename S, typename = void>
struct index_if_impl : index_if_impl<S, when<true>> { };
struct index_if_t {
template <typename Xs, typename Pred>
constexpr auto operator()(Xs&& xs, Pred&& pred) const;
};
constexpr index_if_t index_if{};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_INDEX_IF_HPP

View File

@@ -15,39 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! Returns the intersection of two sets.
//! @relates hana::set
//!
//! Given two sets `xs` and `ys`, `intersection(xs, ys)` is a new set
//! containing exactly those elements that are present both in `xs` and
//! in `ys`. In other words, the following holds for any object `x`:
//! @code
//! x ^in^ intersection(xs, ys) if and only if x ^in^ xs && x ^in^ ys
//! @endcode
//!
//!
//! @param xs, ys
//! Two sets to intersect.
//!
//!
//! Example
//! -------
//! @include example/intersection.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto intersection = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#else
// Note: This function is documented per datatype/concept only.
//! @cond
template <typename S, typename = void>
struct intersection_impl : intersection_impl<S, when<true>> { };
//! @endcond
struct intersection_t {
template <typename Xs, typename Ys>
constexpr auto operator()(Xs&& xs, Ys&& ys) const;
constexpr auto operator()(Xs&&, Ys&&) const;
};
constexpr intersection_t intersection{};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_INTERSECTION_HPP

View File

@@ -49,7 +49,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct lift_impl : lift_impl<A, when<true>> { };
template <typename A>
struct lift_t;
struct lift_t {
template <typename X>
constexpr auto operator()(X&& x) const;
};
template <typename A>
constexpr lift_t<A> lift{};

View File

@@ -36,21 +36,23 @@ 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 that the actual representation of a `hana::map` is an implementation
//! @note
//! 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 basically equivalent to
//! @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.
//! argument deduction, for example. More details [in the tutorial]
//! (@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
@@ -255,6 +257,126 @@ BOOST_HANA_NAMESPACE_BEGIN
return tag-dispatched;
};
#endif
//! Returns the union of two maps.
//! @relates hana::map
//!
//! Given two maps `xs` and `ys`, `hana::union_(xs, ys)` is a new map
//! containing all the elements of `xs` and all the elements of `ys`,
//! without duplicates. If both `xs` and `ys` contain an element with the
//! same `key`, the one in `ys` is taken. Functionally,
//! `hana::union_(xs, ys)` is equivalent to
//! @code
//! hana::fold_left(xs, ys, hana::insert)
//! @endcode
//!
//! @param xs, ys
//! The two maps to compute the union of.
//!
//!
//! Example
//! -------
//! @include example/map/union.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto union_ = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#endif
//! Returns the intersection of two maps.
//! @relates hana::map
//!
//! Given two maps `xs` and `ys`, `intersection(xs, ys)` is a new map
//! containing exactly those (key, value) pairs from xs, for which key
//! is present in `ys`.
//! In other words, the following holds for any object `pair(k, v)`:
//! @code
//! pair(k, v) ^in^ intersection(xs, ys) if and only if (k, v) ^in^ xs && k ^in^ keys(ys)
//! @endcode
//!
//!
//! @note
//! This function is not commutative, i.e. `intersection(xs, ys)` is not
//! necessarily the same as `intersection(ys, xs)`. Indeed, the set of keys
//! in `intersection(xs, ys)` is always the same as the set of keys in
//! `intersection(ys, xs)`, but the value associated to each key may be
//! different. `intersection(xs, ys)` contains values present in `xs`, and
//! `intersection(ys, xs)` contains values present in `ys`.
//!
//!
//! @param xs, ys
//! Two maps to intersect.
//!
//!
//! Example
//! -------
//! @include example/map/intersection.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto intersection = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#endif
//! Returns the difference of two maps.
//! @relates hana::map
//!
//! Given two maps `xs` and `ys`, `difference(xs, ys)` is a new map
//! containing exactly those (key, value) pairs from xs, for which key
//! is not present in `keys(ys)`.
//! In other words, the following holds for any object `pair(k, v)`:
//! @code
//! pair(k, v) ^in^ difference(xs, ys) if and only if (k, v) ^in^ xs && k ^not in^ keys(ys)
//! @endcode
//!
//!
//! @note
//! This function is not commutative, i.e. `difference(xs, ys)` is not
//! necessarily the same as `difference(ys, xs)`.
//! Indeed, consider the case where `xs` is empty and `ys` isn't.
//! In that case, `difference(xs, ys)` is empty, but `difference(ys, xs)`
//! is equal to `ys`.
//! For symmetric version of this operation, see `symmetric_difference`.
//!
//!
//! @param xs, ys
//! Two maps to compute the difference of.
//!
//!
//! Example
//! -------
//! @include example/map/intersection.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto difference = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#endif
//! Returns the symmetric set-theoretic difference of two maps.
//! @relates hana::map
//!
//! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new
//! map containing all the elements of `xs` whose keys are not contained in `keys(ys)`,
//! and all the elements of `ys` whose keys are not contained in `keys(xs)`. The
//! symmetric difference of two maps satisfies the following:
//! @code
//! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs))
//! @endcode
//!
//!
//! @param xs, ys
//! Two maps to compute the symmetric difference of.
//!
//!
//! Example
//! -------
//! @include example/map/symmetric_difference.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_MAP_HPP

View File

@@ -94,7 +94,13 @@ BOOST_HANA_NAMESPACE_BEGIN
struct monadic_fold_left_impl : monadic_fold_left_impl<T, when<true>> { };
template <typename M>
struct monadic_fold_left_t;
struct monadic_fold_left_t {
template <typename Xs, typename State, typename F>
constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const;
template <typename Xs, typename F>
constexpr decltype(auto) operator()(Xs&& xs, F&& f) const;
};
template <typename M>
constexpr monadic_fold_left_t<M> monadic_fold_left{};

View File

@@ -96,7 +96,13 @@ BOOST_HANA_NAMESPACE_BEGIN
struct monadic_fold_right_impl : monadic_fold_right_impl<T, when<true>> { };
template <typename M>
struct monadic_fold_right_t;
struct monadic_fold_right_t {
template <typename Xs, typename State, typename F>
constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const;
template <typename Xs, typename F>
constexpr decltype(auto) operator()(Xs&& xs, F&& f) const;
};
template <typename M>
constexpr monadic_fold_right_t<M> monadic_fold_right{};

View File

@@ -35,7 +35,9 @@ BOOST_HANA_NAMESPACE_BEGIN
struct one_impl : one_impl<R, when<true>> { };
template <typename R>
struct one_t;
struct one_t {
constexpr decltype(auto) operator()() const;
};
template <typename R>
constexpr one_t<R> one{};

View File

@@ -38,6 +38,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! by the compiler. This makes `hana::optional` well suited for static
//! metaprogramming tasks, but very poor for anything dynamic.
//!
//! @note
//! When you use a container, remember not to make assumptions about its
//! representation, unless the documentation gives you those guarantees.
//! More details [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Interoperation with `type`s
//! ---------------------------

View File

@@ -24,6 +24,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! Instead, one must use the `hana::first` and `hana::second` free
//! functions to access the elements of a pair.
//!
//! @note
//! When you use a container, remember not to make assumptions about its
//! representation, unless the documentation gives you those guarantees.
//! More details [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
//! ----------------

View File

@@ -60,7 +60,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct product_impl : product_impl<T, when<true>> { };
template <typename R>
struct product_t;
struct product_t {
template <typename Xs>
constexpr decltype(auto) operator()(Xs&& xs) const;
};
template <typename R = integral_constant_tag<int>>
constexpr product_t<R> product{};

View File

@@ -35,7 +35,8 @@ BOOST_HANA_NAMESPACE_BEGIN
//! The representation of `hana::range` is implementation defined. In
//! particular, one should not take for granted the number and types
//! of template parameters. The proper way to create a `hana::range`
//! is to use `hana::range_c` or `hana::make_range`.
//! is to use `hana::range_c` or `hana::make_range`. More details
//! [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts

View File

@@ -24,7 +24,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//! ---------
//! Given `F` a Functor and `Bool` a Logical, the signature is
//! \f$
//! \mathtt{replace_if} : F(T) \times (T \to Bool) \times T \to F(T)
//! \mathtt{replace\_if} : F(T) \times (T \to Bool) \times T \to F(T)
//! \f$
//!
//! @param xs

View File

@@ -65,7 +65,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct replicate_impl : replicate_impl<M, when<true>> { };
template <typename M>
struct replicate_t;
struct replicate_t {
template <typename X, typename N>
constexpr auto operator()(X&& x, N const& n) const;
};
template <typename M>
constexpr replicate_t<M> replicate{};

View File

@@ -30,7 +30,8 @@ BOOST_HANA_NAMESPACE_BEGIN
//! 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::set` is through `hana::make_set`.
//! creating a `hana::set` is through `hana::make_set`. More details
//! [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
@@ -182,9 +183,116 @@ BOOST_HANA_NAMESPACE_BEGIN
};
#endif
//! Returns the union of two sets.
//! @relates hana::set
//!
//! Given two sets `xs` and `ys`, `union_(xs, ys)` is a new set containing
//! all the elements of `xs` and all the elements of `ys`, without
//! duplicates. For any object `x`, the following holds: `x` is in
//! `hana::union_(xs, ys)` if and only if `x` is in `xs` or `x` is in `ys`.
//!
//!
//! @param xs, ys
//! Two sets to compute the union of.
//!
//!
//! Example
//! -------
//! @include example/set/union.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto union_ = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#endif
//! Returns the intersection of two sets.
//! @relates hana::set
//!
//! Given two sets `xs` and `ys`, `intersection(xs, ys)` is a new set
//! containing exactly those elements that are present both in `xs` and
//! in `ys`.
//! In other words, the following holds for any object `x`:
//! @code
//! x ^in^ intersection(xs, ys) if and only if x ^in^ xs && x ^in^ ys
//! @endcode
//!
//!
//! @param xs, ys
//! Two sets to intersect.
//!
//!
//! Example
//! -------
//! @include example/set/intersection.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto intersection = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#endif
//! Equivalent to `to<set_tag>`; provided for convenience.
//! @relates hana::set
constexpr auto to_set = to<set_tag>;
//! Returns the set-theoretic difference of two sets.
//! @relates hana::set
//!
//! Given two sets `xs` and `ys`, `difference(xs, ys)` is a new set
//! containing all the elements of `xs` that are _not_ contained in `ys`.
//! For any object `x`, the following holds:
//! @code
//! x ^in^ difference(xs, ys) if and only if x ^in^ xs && !(x ^in^ ys)
//! @endcode
//!
//!
//! This operation is not commutative, i.e. `difference(xs, ys)` is not
//! necessarily the same as `difference(ys, xs)`. Indeed, consider the
//! case where `xs` is empty and `ys` isn't. Then, `difference(xs, ys)`
//! is empty but `difference(ys, xs)` is equal to `ys`. For the symmetric
//! version of this operation, see `symmetric_difference`.
//!
//!
//! @param xs
//! A set param to remove values from.
//!
//! @param ys
//! The set whose values are removed from `xs`.
//!
//!
//! Example
//! -------
//! @include example/set/difference.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto difference = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#endif
//! Returns the symmetric set-theoretic difference of two sets.
//! @relates hana::set
//!
//! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new
//! set containing all the elements of `xs` that are not contained in `ys`,
//! and all the elements of `ys` that are not contained in `xs`. The
//! symmetric difference of two sets satisfies the following:
//! @code
//! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs))
//! @endcode
//!
//!
//! @param xs, ys
//! Two sets to compute the symmetric difference of.
//!
//!
//! Example
//! -------
//! @include example/set/symmetric_difference.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_SET_HPP

View File

@@ -12,6 +12,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/fwd/core/make.hpp>
#include <boost/hana/fwd/core/to.hpp>
BOOST_HANA_NAMESPACE_BEGIN
@@ -39,7 +40,8 @@ BOOST_HANA_NAMESPACE_BEGIN
//! 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`,
//! `.c_str()` or `hana::to<char const*>`, as documented below.
//! `.c_str()` or `hana::to<char const*>`, as documented below. More
//! details [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
@@ -94,16 +96,23 @@ BOOST_HANA_NAMESPACE_BEGIN
//! concepts as `hana::string` does.
//! @include example/string/to.cpp
//!
//! Conversion from any Constant holding a `char const*`
//! ----------------------------------------------------
//! A `hana::string` can be created from any `Constant` whose underlying
//! value is convertible to a `char const*` by using `hana::to`. The
//! contents of the `char const*` are used to build the content of the
//! `hana::string`.
//! @include example/string/from_c_str.cpp
//!
//! > #### Rationale for `hana::string` not being a `Constant`
//! > The underlying type held by a `hana::string` could be either
//! > `char const*` or some other constexpr-enabled string-like container.
//! > In the first case, `hana::string` can not be a `Constant` because
//! > the models of several concepts would not be respected by the
//! > underlying type, causing `value` not to be structure-preserving.
//! > Providing an underlying value of constexpr-enabled string-like
//! > container type like `std::string_view` would be great, but that's
//! > a bit complicated for the time being.
//! Rationale for `hana::string` not being a `Constant` itself
//! ----------------------------------------------------------
//! The underlying type held by a `hana::string` could be either `char const*`
//! or some other constexpr-enabled string-like container. In the first case,
//! `hana::string` can not be a `Constant` because the models of several
//! concepts would not be respected by the underlying type, causing `value`
//! not to be structure-preserving. Providing an underlying value of
//! constexpr-enabled string-like container type like `std::string_view`
//! would be great, but that's a bit complicated for the time being.
template <typename implementation_defined>
struct string {
// Default-construct a `hana::string`; no-op since `hana::string` is stateless.
@@ -180,6 +189,10 @@ BOOST_HANA_NAMESPACE_BEGIN
//! @relates hana::string
constexpr auto make_string = make<string_tag>;
//! Equivalent to `to<string_tag>`; provided for convenience.
//! @relates hana::string
constexpr auto to_string = to<string_tag>;
//! Create a compile-time string from a parameter pack of characters.
//! @relates hana::string
//!
@@ -200,7 +213,8 @@ BOOST_HANA_NAMESPACE_BEGIN
//!
//! This macro is a more convenient alternative to `string_c` for creating
//! compile-time strings. However, since this macro uses a lambda
//! internally, it can't be used in an unevaluated context.
//! internally, it can't be used in an unevaluated context, or where
//! a constant expression is expected before C++17.
//!
//!
//! Example

View File

@@ -69,7 +69,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct sum_impl : sum_impl<T, when<true>> { };
template <typename M>
struct sum_t;
struct sum_t {
template <typename Xs>
constexpr decltype(auto) operator()(Xs&& xs) const;
};
template <typename M = integral_constant_tag<int>>
constexpr sum_t<M> sum{};

View File

@@ -15,40 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! Returns the symmetric set-theoretic difference of two sets.
//! @relates hana::set
//!
//! Given two sets `xs` and `ys`, `symmetric_difference(xs, ys)` is a new
//! set containing all the elements of `xs` that are not contained in `ys`,
//! and all the elements of `ys` that are not contained in `xs`. The
//! symmetric difference of two sets satisfies the following:
//! @code
//! symmetric_difference(xs, ys) == union_(difference(xs, ys), difference(ys, xs))
//! @endcode
//!
//!
//! @param xs, ys
//! Two sets to compute the symmetric difference of.
//!
//!
//! Example
//! -------
//! @include example/symmetric_difference.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto symmetric_difference = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#else
// Note: This function is documented per datatype/concept only.
//! @cond
template <typename S, typename = void>
struct symmetric_difference_impl : symmetric_difference_impl<S, when<true>> { };
//! @endcond
struct symmetric_difference_t {
template <typename Xs, typename Ys>
constexpr auto operator()(Xs&& xs, Ys&& ys) const;
constexpr auto operator()(Xs&&, Ys&&) const;
};
constexpr symmetric_difference_t symmetric_difference{};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_SYMMETRIC_DIFFERENCE_HPP

View File

@@ -53,6 +53,26 @@ BOOST_HANA_NAMESPACE_BEGIN
constexpr take_back_t take_back{};
#endif
//! Equivalent to `take_back`; provided for convenience.
//! @ingroup group-Sequence
//!
//!
//! Example
//! -------
//! @include example/take_back_c.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
template <std::size_t n>
constexpr auto take_back_c = [](auto&& xs) {
return hana::take_back(forwarded(xs), hana::size_c<n>);
};
#else
template <std::size_t n>
struct take_back_c_t;
template <std::size_t n>
constexpr take_back_c_t<n> take_back_c{};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_TAKE_BACK_HPP

View File

@@ -55,7 +55,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct tap_impl : tap_impl<M, when<true>> { };
template <typename M>
struct tap_t;
struct tap_t {
template <typename F>
constexpr auto operator()(F&& f) const;
};
template <typename M>
constexpr tap_t<M> tap{};

View File

@@ -32,6 +32,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! sequence with a key-based access, then you should consider
//! `hana::map` or `hana::set` instead.
//!
//! @note
//! When you use a container, remember not to make assumptions about its
//! representation, unless the documentation gives you those guarantees.
//! More details [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
//! ----------------

View File

@@ -394,15 +394,13 @@ BOOST_HANA_NAMESPACE_BEGIN
//! @endcode
//!
//! @note
//! `template_` can't be SFINAE-friendly right now because of
//! [Core issue 1430][1].
//! In a SFINAE context, the expression `template_<f>(type_c<x>...)` is
//! valid whenever the expression `f<x...>` is valid.
//!
//!
//! Example
//! -------
//! @include example/type/template.cpp
//!
//! [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>...) {
@@ -426,6 +424,10 @@ BOOST_HANA_NAMESPACE_BEGIN
//! decltype(metafunction<f>)::apply<x...>::type == f<x...>::type
//! @endcode
//!
//! @note
//! In a SFINAE context, the expression `metafunction<f>(type_c<x>...)` is
//! valid whenever the expression `f<x...>::%type` is valid.
//!
//!
//! Example
//! -------
@@ -453,6 +455,10 @@ BOOST_HANA_NAMESPACE_BEGIN
//! decltype(metafunction_class<f>)::apply<x...>::type == f::apply<x...>::type
//! @endcode
//!
//! @note
//! In a SFINAE context, the expression `metafunction_class<f>(type_c<x>...)`
//! is valid whenever the expression `f::apply<x...>::%type` is valid.
//!
//!
//! Example
//! -------
@@ -464,9 +470,7 @@ BOOST_HANA_NAMESPACE_BEGIN
};
#else
template <typename F>
struct metafunction_class_t
: metafunction_t<F::template apply>
{ };
struct metafunction_class_t;
template <typename F>
constexpr metafunction_class_t<F> metafunction_class{};
@@ -498,6 +502,9 @@ BOOST_HANA_NAMESPACE_BEGIN
//! boost/hana/ext/std/integral_constant.hpp header to ensure
//! Hana can interoperate with the result.
//!
//! - In a SFINAE context, the expression `integral(f)(t...)` is valid
//! whenever the expression `decltype(f(t...))::%type` is valid.
//!
//!
//! Example
//! -------

View File

@@ -15,39 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! Returns the union of two sets.
//! @relates hana::set
//!
//! Given two sets `xs` and `ys`, `union_(xs, ys)` is a new set containing
//! all the elements of `xs` and all the elements of `ys`, without
//! duplicates. For any object `x`, the following holds:
//! @code
//! x ^in^ union_(xs, ys) if and only if x ^in^ xs || x ^in^ ys
//! @endcode
//!
//!
//! @param xs, ys
//! Two sets to compute the union of.
//!
//!
//! Example
//! -------
//! @include example/union.cpp
#ifdef BOOST_HANA_DOXYGEN_INVOKED
constexpr auto union_ = [](auto&& xs, auto&& ys) {
return tag-dispatched;
};
#else
template <typename S, typename = void>
struct union_impl : union_impl<S, when<true>> { };
// Note: This function is documented per datatype/concept only.
//! @cond
template <typename T, typename = void>
struct union_impl : union_impl<T, when<true>> { };
//! @endcond
struct union_t {
template <typename Xs, typename Ys>
constexpr auto operator()(Xs&& xs, Ys&& ys) const;
constexpr auto operator()(Xs&&, Ys&&) const;
};
constexpr union_t union_{};
#endif
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_FWD_UNION_HPP

View File

@@ -35,7 +35,9 @@ BOOST_HANA_NAMESPACE_BEGIN
struct zero_impl : zero_impl<M, when<true>> { };
template <typename M>
struct zero_t;
struct zero_t {
constexpr decltype(auto) operator()() const;
};
template <typename M>
constexpr zero_t<M> zero{};

View File

@@ -78,7 +78,7 @@ BOOST_HANA_NAMESPACE_BEGIN
template <bool ...b>
struct group_indices {
static constexpr bool bs[] = {b...};
static constexpr bool bs[sizeof...(b)] = {b...};
static constexpr std::size_t n_groups =
detail::count(bs, bs + sizeof(bs), false) + 1;

View File

@@ -0,0 +1,105 @@
/*!
@file
Defines `boost::hana::index_if`.
@copyright Louis Dionne 2013-2017
@copyright Jason Rice 2017
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_INDEX_IF_HPP
#define BOOST_HANA_INDEX_IF_HPP
#include <boost/hana/concept/foldable.hpp>
#include <boost/hana/concept/iterable.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/detail/decay.hpp>
#include <boost/hana/detail/index_if.hpp>
#include <boost/hana/fwd/at.hpp>
#include <boost/hana/fwd/basic_tuple.hpp>
#include <boost/hana/fwd/index_if.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/length.hpp>
#include <boost/hana/optional.hpp>
#include <cstddef>
#include <utility>
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename Xs, typename Pred>
constexpr auto index_if_t::operator()(Xs&& xs, Pred&& pred) const {
using S = typename hana::tag_of<Xs>::type;
using IndexIf = BOOST_HANA_DISPATCH_IF(index_if_impl<S>,
hana::Iterable<S>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Iterable<S>::value,
"hana::index_if(xs, pred) requires 'xs' to be a Iterable");
#endif
return IndexIf::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred));
}
//! @endcond
namespace detail {
template <std::size_t i, std::size_t N, bool Done>
struct iterate_while;
template <std::size_t i, std::size_t N>
struct iterate_while<i, N, false> {
template <typename Xs, typename Pred>
using f = typename iterate_while<i + 1, N,
static_cast<bool>(detail::decay<decltype(
std::declval<Pred>()(
hana::at(std::declval<Xs>(), hana::size_c<i>)))>::type::value)
>::template f<Xs, Pred>;
};
template <std::size_t N>
struct iterate_while<N, N, false> {
template <typename Xs, typename Pred>
using f = hana::optional<>;
};
template <std::size_t i, std::size_t N>
struct iterate_while<i, N, true> {
template <typename Xs, typename Pred>
using f = hana::optional<hana::size_t<i - 1>>;
};
}
template <typename Tag>
struct index_if_impl<Tag, when<Foldable<Tag>::value>> {
template <typename Xs, typename Pred>
static constexpr auto apply(Xs const& xs, Pred const&)
-> typename detail::iterate_while<0,
decltype(hana::length(xs))::value, false>
::template f<Xs, Pred>
{ return {}; }
};
template <typename It>
struct index_if_impl<It, when<!Foldable<It>::value>> {
template <typename Xs, typename Pred>
static constexpr auto apply(Xs const&, Pred const&)
-> typename detail::iterate_while<0,
static_cast<std::size_t>(-1), false>
::template f<Xs, Pred>
{ return {}; }
};
// basic_tuple is implemented here to solve circular dependency issues.
template <>
struct index_if_impl<basic_tuple_tag> {
template <typename ...Xs, typename Pred>
static constexpr auto apply(basic_tuple<Xs...> const&, Pred const&)
-> typename detail::index_if<Pred, Xs...>::type
{ return {}; }
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_INDEX_IF_HPP

View File

@@ -20,22 +20,22 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename A>
struct lift_t {
template <typename X>
constexpr auto lift_t<A>::operator()(X&& x) const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Applicative<A>::value,
"hana::lift<A> requires 'A' to be an Applicative");
#endif
template <typename X>
constexpr auto operator()(X&& x) const {
using Lift = BOOST_HANA_DISPATCH_IF(lift_impl<A>,
hana::Applicative<A>::value
);
using Lift = BOOST_HANA_DISPATCH_IF(lift_impl<A>,
hana::Applicative<A>::value
);
return Lift::apply(static_cast<X&&>(x));
}
};
return Lift::apply(static_cast<X&&>(x));
}
//! @endcond
template <typename A, bool condition>
struct lift_impl<A, when<condition>> : default_ {

View File

@@ -40,9 +40,12 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/functional/partial.hpp>
#include <boost/hana/fwd/any_of.hpp>
#include <boost/hana/fwd/at_key.hpp>
#include <boost/hana/fwd/difference.hpp>
#include <boost/hana/fwd/erase_key.hpp>
#include <boost/hana/fwd/intersection.hpp>
#include <boost/hana/fwd/is_subset.hpp>
#include <boost/hana/fwd/keys.hpp>
#include <boost/hana/fwd/union.hpp>
#include <boost/hana/insert.hpp>
#include <boost/hana/integral_constant.hpp>
#include <boost/hana/keys.hpp>
@@ -53,6 +56,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/unpack.hpp>
#include <boost/hana/value.hpp>
#include <cstddef>
#include <type_traits>
#include <utility>
@@ -120,7 +124,7 @@ BOOST_HANA_NAMESPACE_BEGIN
};
template <typename HashTable, typename Storage>
struct map_impl
struct map_impl final
: detail::searchable_operators<map_impl<HashTable, Storage>>
, detail::operators::adl<map_impl<HashTable, Storage>>
{
@@ -479,6 +483,71 @@ BOOST_HANA_NAMESPACE_BEGIN
}
};
//////////////////////////////////////////////////////////////////////////
// union_
//////////////////////////////////////////////////////////////////////////
template <>
struct union_impl<map_tag> {
template <typename Xs, typename Ys>
static constexpr auto apply(Xs&& xs, Ys&& ys) {
return hana::fold_left(static_cast<Xs&&>(xs), static_cast<Ys&&>(ys),
hana::insert);
}
};
//////////////////////////////////////////////////////////////////////////
// intersection_
//////////////////////////////////////////////////////////////////////////
namespace detail {
template <typename Ys>
struct map_insert_if_contains {
Ys const& ys;
// Second template param will be pair
// Get its key and check if it exists, if it does, insert key, value pair.
template <typename Result, typename Pair>
static constexpr auto helper(Result&& result, Pair&& pair, hana::true_) {
return hana::insert(static_cast<Result&&>(result), static_cast<Pair&&>(pair));
}
template <typename Result, typename Pair>
static constexpr auto helper(Result&& result, Pair&&, hana::false_) {
return static_cast<Result&&>(result);
}
template <typename Result, typename Pair>
constexpr auto operator()(Result&& result, Pair&& pair) const {
constexpr bool keep = hana::value<decltype(hana::contains(ys, hana::first(pair)))>();
return map_insert_if_contains::helper(static_cast<Result&&>(result),
static_cast<Pair&&>(pair),
hana::bool_c<keep>);
}
};
}
template <>
struct intersection_impl<map_tag> {
template <typename Xs, typename Ys>
static constexpr auto apply(Xs&& xs, Ys const& ys) {
return hana::fold_left(static_cast<Xs&&>(xs), hana::make_map(),
detail::map_insert_if_contains<Ys>{ys});
}
};
//////////////////////////////////////////////////////////////////////////
// difference
//////////////////////////////////////////////////////////////////////////
template <>
struct difference_impl<map_tag> {
template <typename Xs, typename Ys>
static constexpr auto apply(Xs&& xs, Ys&& ys) {
return hana::fold_left(
hana::keys(static_cast<Ys&&>(ys)),
static_cast<Xs&&>(xs),
hana::erase_key);
}
};
//////////////////////////////////////////////////////////////////////////
// Foldable
//////////////////////////////////////////////////////////////////////////

View File

@@ -27,46 +27,50 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename M>
struct monadic_fold_left_t {
template <typename Xs, typename State, typename F>
constexpr decltype(auto) monadic_fold_left_t<M>::operator()(Xs&& xs, State&& state, F&& f) const {
using S = typename hana::tag_of<Xs>::type;
using MonadicFoldLeft = BOOST_HANA_DISPATCH_IF(monadic_fold_left_impl<S>,
hana::Foldable<S>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monad<M>::value,
"hana::monadic_fold_left<M> requires 'M' to be a Monad");
static_assert(hana::Foldable<S>::value,
"hana::monadic_fold_left<M>(xs, state, f) requires 'xs' to be Foldable");
#endif
template <typename Xs, typename State, typename F>
constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const {
using S = typename hana::tag_of<Xs>::type;
using MonadicFoldLeft = BOOST_HANA_DISPATCH_IF(monadic_fold_left_impl<S>,
hana::Foldable<S>::value
);
return MonadicFoldLeft::template apply<M>(static_cast<Xs&&>(xs),
static_cast<State&&>(state),
static_cast<F&&>(f));
}
//! @endcond
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Foldable<S>::value,
"hana::monadic_fold_left<M>(xs, state, f) requires 'xs' to be Foldable");
#endif
//! @cond
template <typename M>
template <typename Xs, typename F>
constexpr decltype(auto) monadic_fold_left_t<M>::operator()(Xs&& xs, F&& f) const {
using S = typename hana::tag_of<Xs>::type;
using MonadicFoldLeft = BOOST_HANA_DISPATCH_IF(monadic_fold_left_impl<S>,
hana::Foldable<S>::value
);
return MonadicFoldLeft::template apply<M>(static_cast<Xs&&>(xs),
static_cast<State&&>(state),
static_cast<F&&>(f));
}
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monad<M>::value,
"hana::monadic_fold_left<M> requires 'M' to be a Monad");
template <typename Xs, typename F>
constexpr decltype(auto) operator()(Xs&& xs, F&& f) const {
using S = typename hana::tag_of<Xs>::type;
using MonadicFoldLeft = BOOST_HANA_DISPATCH_IF(monadic_fold_left_impl<S>,
hana::Foldable<S>::value
);
static_assert(hana::Foldable<S>::value,
"hana::monadic_fold_left<M>(xs, f) requires 'xs' to be Foldable");
#endif
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Foldable<S>::value,
"hana::monadic_fold_left<M>(xs, f) requires 'xs' to be Foldable");
#endif
return MonadicFoldLeft::template apply<M>(static_cast<Xs&&>(xs),
static_cast<F&&>(f));
}
};
return MonadicFoldLeft::template apply<M>(static_cast<Xs&&>(xs),
static_cast<F&&>(f));
}
//! @endcond
namespace detail {
struct foldlM_helper {

View File

@@ -27,45 +27,49 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename M>
struct monadic_fold_right_t {
template <typename Xs, typename State, typename F>
constexpr decltype(auto) monadic_fold_right_t<M>::operator()(Xs&& xs, State&& state, F&& f) const {
using S = typename hana::tag_of<Xs>::type;
using MonadicFoldRight = BOOST_HANA_DISPATCH_IF(monadic_fold_right_impl<S>,
hana::Foldable<S>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monad<M>::value,
"hana::monadic_fold_right<M> requires 'M' to be a Monad");
static_assert(hana::Foldable<S>::value,
"hana::monadic_fold_right<M>(xs, state, f) requires 'xs' to be Foldable");
#endif
template <typename Xs, typename State, typename F>
constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const {
using S = typename hana::tag_of<Xs>::type;
using MonadicFoldRight = BOOST_HANA_DISPATCH_IF(monadic_fold_right_impl<S>,
hana::Foldable<S>::value
);
return MonadicFoldRight::template apply<M>(static_cast<Xs&&>(xs),
static_cast<State&&>(state),
static_cast<F&&>(f));
}
//! @endcond
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Foldable<S>::value,
"hana::monadic_fold_right<M>(xs, state, f) requires 'xs' to be Foldable");
#endif
//! @cond
template <typename M>
template <typename Xs, typename F>
constexpr decltype(auto) monadic_fold_right_t<M>::operator()(Xs&& xs, F&& f) const {
using S = typename hana::tag_of<Xs>::type;
using MonadicFoldRight = BOOST_HANA_DISPATCH_IF(monadic_fold_right_impl<S>,
hana::Foldable<S>::value
);
return MonadicFoldRight::template apply<M>(static_cast<Xs&&>(xs),
static_cast<State&&>(state),
static_cast<F&&>(f));
}
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monad<M>::value,
"hana::monadic_fold_right<M> requires 'M' to be a Monad");
template <typename Xs, typename F>
constexpr decltype(auto) operator()(Xs&& xs, F&& f) const {
using S = typename hana::tag_of<Xs>::type;
using MonadicFoldRight = BOOST_HANA_DISPATCH_IF(monadic_fold_right_impl<S>,
hana::Foldable<S>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Foldable<S>::value,
"hana::monadic_fold_right<M>(xs, f) requires 'xs' to be Foldable");
#endif
return MonadicFoldRight::template apply<M>(static_cast<Xs&&>(xs),
static_cast<F&&>(f));
}
};
static_assert(hana::Foldable<S>::value,
"hana::monadic_fold_right<M>(xs, f) requires 'xs' to be Foldable");
#endif
return MonadicFoldRight::template apply<M>(static_cast<Xs&&>(xs),
static_cast<F&&>(f));
}
//! @endcond
namespace detail {
struct foldrM_helper {

View File

@@ -23,21 +23,21 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename R>
struct one_t {
constexpr decltype(auto) one_t<R>::operator()() const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Ring<R>::value,
"hana::one<R>() requires 'R' to be a Ring");
#endif
constexpr decltype(auto) operator()() const {
using One = BOOST_HANA_DISPATCH_IF(one_impl<R>,
hana::Ring<R>::value
);
using One = BOOST_HANA_DISPATCH_IF(one_impl<R>,
hana::Ring<R>::value
);
return One::apply();
}
};
return One::apply();
}
//! @endcond
template <typename R, bool condition>
struct one_impl<R, when<condition>> : default_ {

View File

@@ -79,8 +79,8 @@ BOOST_HANA_NAMESPACE_BEGIN
BOOST_HANA_TT_IS_CONVERTIBLE(U const&, Second)
>::type>
constexpr pair(pair<T, U> const& other)
: detail::ebo<detail::pix<0>, First>(detail::ebo_get<detail::pix<0>>(other))
, detail::ebo<detail::pix<1>, Second>(detail::ebo_get<detail::pix<1>>(other))
: detail::ebo<detail::pix<0>, First>(hana::first(other))
, detail::ebo<detail::pix<1>, Second>(hana::second(other))
{ }
template <typename T, typename U, typename = typename std::enable_if<
@@ -90,8 +90,8 @@ BOOST_HANA_NAMESPACE_BEGIN
BOOST_HANA_TT_IS_CONVERTIBLE(U&&, Second)
>::type>
constexpr pair(pair<T, U>&& other)
: detail::ebo<detail::pix<0>, First>(static_cast<T&&>(detail::ebo_get<detail::pix<0>>(other)))
, detail::ebo<detail::pix<1>, Second>(static_cast<U&&>(detail::ebo_get<detail::pix<1>>(other)))
: detail::ebo<detail::pix<0>, First>(hana::first(static_cast<pair<T, U>&&>(other)))
, detail::ebo<detail::pix<1>, Second>(hana::second(static_cast<pair<T, U>&&>(other)))
{ }
@@ -101,8 +101,8 @@ BOOST_HANA_NAMESPACE_BEGIN
BOOST_HANA_TT_IS_ASSIGNABLE(Second&, U const&)
>::type>
constexpr pair& operator=(pair<T, U> const& other) {
detail::ebo_get<detail::pix<0>>(*this) = detail::ebo_get<detail::pix<0>>(other);
detail::ebo_get<detail::pix<1>>(*this) = detail::ebo_get<detail::pix<1>>(other);
hana::first(*this) = hana::first(other);
hana::second(*this) = hana::second(other);
return *this;
}
@@ -111,8 +111,8 @@ BOOST_HANA_NAMESPACE_BEGIN
BOOST_HANA_TT_IS_ASSIGNABLE(Second&, U&&)
>::type>
constexpr pair& operator=(pair<T, U>&& other) {
detail::ebo_get<detail::pix<0>>(*this) = static_cast<T&&>(detail::ebo_get<detail::pix<0>>(other));
detail::ebo_get<detail::pix<1>>(*this) = static_cast<U&&>(detail::ebo_get<detail::pix<1>>(other));
hana::first(*this) = hana::first(static_cast<pair<T, U>&&>(other));
hana::second(*this) = hana::second(static_cast<pair<T, U>&&>(other));
return *this;
}

View File

@@ -49,9 +49,9 @@ BOOST_HANA_NAMESPACE_BEGIN
namespace detail {
template <bool ...B>
struct partition_indices {
static constexpr bool results[] = {B..., false}; // avoid empty array
static constexpr detail::array<bool, sizeof...(B)> results{{B...}};
static constexpr std::size_t left_size =
detail::count(results, results + sizeof...(B), true);
detail::count(results.begin(), results.end(), true);
static constexpr std::size_t right_size = sizeof...(B) - left_size;
static constexpr auto compute_left() {

View File

@@ -23,28 +23,26 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename R>
struct product_t {
template <typename Xs>
constexpr decltype(auto) product_t<R>::operator()(Xs&& xs) const {
using S = typename hana::tag_of<Xs>::type;
using Product = BOOST_HANA_DISPATCH_IF(product_impl<S>,
hana::Foldable<S>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Ring<R>::value,
"hana::product<R> requires 'R' to be a Ring");
static_assert(hana::Foldable<S>::value,
"hana::product<R>(xs) requires 'xs' to be Foldable");
#endif
template <typename Xs>
constexpr decltype(auto) operator()(Xs&& xs) const {
using S = typename hana::tag_of<Xs>::type;
using Product = BOOST_HANA_DISPATCH_IF(product_impl<S>,
hana::Foldable<S>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Foldable<S>::value,
"hana::product<R>(xs) requires 'xs' to be Foldable");
#endif
return Product::template apply<R>(static_cast<Xs&&>(xs));
}
};
return Product::template apply<R>(static_cast<Xs&&>(xs));
}
//! @endcond
template <typename T, bool condition>
struct product_impl<T, when<condition>> : default_ {

View File

@@ -25,28 +25,26 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename M>
struct replicate_t {
template <typename X, typename N>
constexpr auto replicate_t<M>::operator()(X&& x, N const& n) const {
using Replicate = BOOST_HANA_DISPATCH_IF(replicate_impl<M>,
hana::MonadPlus<M>::value &&
hana::IntegralConstant<N>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::MonadPlus<M>::value,
"hana::replicate<M>(x, n) requires 'M' to be a MonadPlus");
static_assert(hana::IntegralConstant<N>::value,
"hana::replicate<M>(x, n) requires 'n' to be an IntegralConstant");
#endif
template <typename X, typename N>
constexpr auto operator()(X&& x, N const& n) const {
using Replicate = BOOST_HANA_DISPATCH_IF(replicate_impl<M>,
hana::MonadPlus<M>::value &&
hana::IntegralConstant<N>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::IntegralConstant<N>::value,
"hana::replicate<M>(x, n) requires 'n' to be an IntegralConstant");
#endif
return Replicate::apply(static_cast<X&&>(x), n);
}
};
return Replicate::apply(static_cast<X&&>(x), n);
}
//! @endcond
template <typename M, bool condition>
struct replicate_impl<M, when<condition>> : default_ {

View File

@@ -56,7 +56,7 @@ BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
//! @cond
template <typename ...Xs>
struct set
struct set final
: detail::operators::adl<set<Xs...>>
, detail::searchable_operators<set<Xs...>>
{

View File

@@ -13,6 +13,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/fwd/string.hpp>
#include <boost/hana/bool.hpp>
#include <boost/hana/concept/constant.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/core/make.hpp>
#include <boost/hana/detail/algorithm.hpp>
@@ -147,6 +148,35 @@ BOOST_HANA_NAMESPACE_BEGIN
{ return string<c...>::c_str(); }
};
//////////////////////////////////////////////////////////////////////////
// to<string_tag>
//////////////////////////////////////////////////////////////////////////
namespace detail {
constexpr std::size_t cx_strlen(char const* s) {
std::size_t n = 0u;
while (*s != '\0')
++s, ++n;
return n;
}
template <typename S, std::size_t ...I>
constexpr hana::string<hana::value<S>()[I]...> expand(std::index_sequence<I...>)
{ return {}; }
}
template <typename IC>
struct to_impl<hana::string_tag, IC, hana::when<
hana::Constant<IC>::value &&
std::is_convertible<typename IC::value_type, char const*>::value
>> {
template <typename S>
static constexpr auto apply(S const&) {
constexpr char const* s = hana::value<S>();
constexpr std::size_t len = detail::cx_strlen(s);
return detail::expand<S>(std::make_index_sequence<len>{});
}
};
//////////////////////////////////////////////////////////////////////////
// Comparable
//////////////////////////////////////////////////////////////////////////

View File

@@ -23,28 +23,26 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename M>
struct sum_t {
template <typename Xs>
constexpr decltype(auto) sum_t<M>::operator()(Xs&& xs) const {
using S = typename hana::tag_of<Xs>::type;
using Sum = BOOST_HANA_DISPATCH_IF(sum_impl<S>,
hana::Foldable<S>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monoid<M>::value,
"hana::sum<M> requires 'M' to be a Monoid");
static_assert(hana::Foldable<S>::value,
"hana::sum<M>(xs) requires 'xs' to be Foldable");
#endif
template <typename Xs>
constexpr decltype(auto) operator()(Xs&& xs) const {
using S = typename hana::tag_of<Xs>::type;
using Sum = BOOST_HANA_DISPATCH_IF(sum_impl<S>,
hana::Foldable<S>::value
);
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Foldable<S>::value,
"hana::sum<M>(xs) requires 'xs' to be Foldable");
#endif
return Sum::template apply<M>(static_cast<Xs&&>(xs));
}
};
return Sum::template apply<M>(static_cast<Xs&&>(xs));
}
//! @endcond
template <typename T, bool condition>
struct sum_impl<T, when<condition>> : default_ {

View File

@@ -63,6 +63,14 @@ BOOST_HANA_NAMESPACE_BEGIN
std::make_index_sequence<(n < len ? n : len)>{});
}
};
template <std::size_t n>
struct take_back_c_t {
template <typename Xs>
constexpr auto operator()(Xs&& xs) const {
return hana::take_back(static_cast<Xs&&>(xs), hana::size_c<n>);
}
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_TAKE_BACK_HPP

View File

@@ -20,22 +20,22 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename M>
struct tap_t {
template <typename F>
constexpr auto tap_t<M>::operator()(F&& f) const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monad<M>::value,
"hana::tap<M> requires 'M' to be a Monad");
#endif
template <typename F>
constexpr auto operator()(F&& f) const {
using Tap = BOOST_HANA_DISPATCH_IF(tap_impl<M>,
hana::Monad<M>::value
);
using Tap = BOOST_HANA_DISPATCH_IF(tap_impl<M>,
hana::Monad<M>::value
);
return Tap::apply(static_cast<F&&>(f));
}
};
return Tap::apply(static_cast<F&&>(f));
}
//! @endcond
namespace detail {
template <typename M>

View File

@@ -3,6 +3,7 @@
Defines `boost::hana::tuple`.
@copyright Louis Dionne 2013-2017
@copyright Jason Rice 2017
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
@@ -27,7 +28,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/fwd/at.hpp>
#include <boost/hana/fwd/core/make.hpp>
#include <boost/hana/fwd/drop_front.hpp>
#include <boost/hana/fwd/find_if.hpp>
#include <boost/hana/fwd/index_if.hpp>
#include <boost/hana/fwd/is_empty.hpp>
#include <boost/hana/fwd/length.hpp>
#include <boost/hana/fwd/optional.hpp>
@@ -74,7 +75,7 @@ BOOST_HANA_NAMESPACE_BEGIN
// tuple
//////////////////////////////////////////////////////////////////////////
template <>
struct tuple<>
struct tuple<> final
: detail::operators::adl<tuple<>>
, detail::iterable_operators<tuple<>>
{
@@ -83,7 +84,7 @@ BOOST_HANA_NAMESPACE_BEGIN
};
template <typename ...Xn>
struct tuple
struct tuple final
: detail::operators::adl<tuple<Xn...>>
, detail::iterable_operators<tuple<Xn...>>
{
@@ -140,7 +141,7 @@ BOOST_HANA_NAMESPACE_BEGIN
// The three following constructors are required to make sure that
// the tuple(Yn&&...) constructor is _not_ preferred over the copy
// constructor for unary tuples containing a type that is constructible
// from tuple<...>. See test/tuple/trap_construct.cpp
// from tuple<...>. See test/tuple/cnstr.trap.cpp
template <typename ...dummy, typename = typename std::enable_if<
detail::fast_and<BOOST_HANA_TT_IS_CONSTRUCTIBLE(Xn, Xn const&, dummy...)...>::value
>::type>
@@ -283,6 +284,14 @@ BOOST_HANA_NAMESPACE_BEGIN
return hana::at_c<n>(static_cast<tuple<Xs...>&&>(xs).storage_);
}
template <>
struct index_if_impl<tuple_tag> {
template <typename ...Xs, typename Pred>
static constexpr auto apply(tuple<Xs...> const&, Pred const&)
-> typename detail::index_if<Pred, Xs...>::type
{ return {}; }
};
//////////////////////////////////////////////////////////////////////////
// Sequence
//////////////////////////////////////////////////////////////////////////
@@ -298,27 +307,6 @@ BOOST_HANA_NAMESPACE_BEGIN
tuple<typename detail::decay<Xs>::type...> apply(Xs&& ...xs)
{ return {static_cast<Xs&&>(xs)...}; }
};
template <>
struct find_if_impl<tuple_tag> {
template <std::size_t index, typename Xs>
static constexpr auto helper(Xs&&, hana::true_) {
return hana::nothing;
}
template <std::size_t index, typename Xs>
static constexpr auto helper(Xs&& xs, hana::false_) {
return hana::just(hana::at_c<index>(static_cast<Xs&&>(xs)));
}
template <typename Xs, typename Pred>
static constexpr auto apply(Xs&& xs, Pred&&) {
using Pack = typename detail::make_pack<Xs>::type;
constexpr std::size_t index = detail::index_if<Pred&&, Pack>::value;
constexpr std::size_t len = Pack::length;
return helper<index>(static_cast<Xs&&>(xs), hana::bool_c<index == len>);
}
};
BOOST_HANA_NAMESPACE_END
#endif // !BOOST_HANA_TUPLE_HPP

View File

@@ -14,6 +14,7 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/bool.hpp>
#include <boost/hana/config.hpp>
#include <boost/hana/core/when.hpp>
#include <boost/hana/detail/operators/adl.hpp>
#include <boost/hana/detail/operators/comparable.hpp>
#include <boost/hana/fwd/concept/metafunction.hpp>
@@ -152,6 +153,24 @@ BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
// template_
//////////////////////////////////////////////////////////////////////////
// Note: We have to use the very complicated trick below instead of just
// mentionning `F<T...>` in a SFINAE-able context because of CWG 1430
// (http://www.open-std.org/Jtc1/sc22/wg21/docs/cwg_active.html#1430).
namespace template_detail {
template <typename ...T> struct args;
template <typename ...> using always_void = void;
template <template <typename ...> class F, typename Args, typename = void>
struct specialization_is_valid
: std::false_type
{ };
template <template <typename ...> class F, typename ...T>
struct specialization_is_valid<F, args<T...>, always_void<F<T...>>>
: std::true_type
{ };
} // end namespace detail
template <template <typename ...> class F>
struct template_t {
template <typename ...T>
@@ -159,7 +178,9 @@ BOOST_HANA_NAMESPACE_BEGIN
using type = F<T...>;
};
template <typename ...T>
template <typename ...T, typename = std::enable_if_t<
template_detail::specialization_is_valid<F, template_detail::args<typename T::type...>>::value
>>
constexpr auto operator()(T const& ...) const
{ return hana::type<F<typename T::type...>>{}; }
};
@@ -177,6 +198,23 @@ BOOST_HANA_NAMESPACE_BEGIN
operator()(T const& ...) const { return {}; }
};
//////////////////////////////////////////////////////////////////////////
// metafunction_class
//////////////////////////////////////////////////////////////////////////
namespace detail {
template <typename F, typename ...T>
struct always_first { using type = F; };
}
template <typename F>
struct metafunction_class_t {
template <typename ...T>
using apply = typename detail::always_first<F, T...>::type::template apply<T...>;
template <typename ...T>
constexpr hana::type<typename detail::always_first<F, T...>::type::template apply<typename T::type...>::type>
operator()(T const& ...) const { return {}; }
};
//////////////////////////////////////////////////////////////////////////
// Metafunction
//////////////////////////////////////////////////////////////////////////
@@ -200,9 +238,10 @@ BOOST_HANA_NAMESPACE_BEGIN
//////////////////////////////////////////////////////////////////////////
template <typename F>
struct integral_t {
template <typename ...T>
constexpr auto operator()(T const& ...) const {
using Result = typename F::template apply<typename T::type...>::type;
template <typename ...T, typename Result =
typename detail::always_first<F, T...>::type::template apply<typename T::type...>::type
>
constexpr Result operator()(T const& ...) const {
return Result{};
}
};

View File

@@ -24,7 +24,7 @@ Distributed under the Boost Software License, Version 1.0.
//! @ingroup group-config
//! Macro expanding to the minor version of the library, i.e. the `y` in `x.y.z`.
#define BOOST_HANA_MINOR_VERSION 1
#define BOOST_HANA_MINOR_VERSION 5
//! @ingroup group-config
//! Macro expanding to the patch level of the library, i.e. the `z` in `x.y.z`.

View File

@@ -23,21 +23,21 @@ Distributed under the Boost Software License, Version 1.0.
BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename M>
struct zero_t {
constexpr decltype(auto) zero_t<M>::operator()() const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::Monoid<M>::value,
"hana::zero<M>() requires 'M' to be a Monoid");
#endif
constexpr decltype(auto) operator()() const {
using Zero = BOOST_HANA_DISPATCH_IF(zero_impl<M>,
hana::Monoid<M>::value
);
using Zero = BOOST_HANA_DISPATCH_IF(zero_impl<M>,
hana::Monoid<M>::value
);
return Zero::apply();
}
};
return Zero::apply();
}
//! @endcond
template <typename M, bool condition>
struct zero_impl<M, when<condition>> : default_ {