update boost on linux
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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--;) {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__, )
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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_ {
|
||||
|
||||
@@ -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>");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
//! ----------------
|
||||
|
||||
@@ -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;
|
||||
//! };
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{};
|
||||
|
||||
60
linx64/include/boost/hana/fwd/index_if.hpp
Normal file
60
linx64/include/boost/hana/fwd/index_if.hpp
Normal 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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
|
||||
//! ---------------------------
|
||||
|
||||
@@ -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
|
||||
//! ----------------
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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
|
||||
//! ----------------
|
||||
|
||||
@@ -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
|
||||
//! -------
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{};
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
105
linx64/include/boost/hana/index_if.hpp
Normal file
105
linx64/include/boost/hana/index_if.hpp
Normal 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
|
||||
@@ -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_ {
|
||||
|
||||
@@ -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
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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_ {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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_ {
|
||||
|
||||
@@ -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_ {
|
||||
|
||||
@@ -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...>>
|
||||
{
|
||||
|
||||
@@ -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
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -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_ {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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{};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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_ {
|
||||
|
||||
Reference in New Issue
Block a user