my push
This commit is contained in:
parent
904fbf80b1
commit
3dd696ce76
@ -0,0 +1,40 @@
|
||||
/*!
|
||||
@file
|
||||
Defines operators for Searchables.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_OPERATORS_SEARCHABLE_HPP
|
||||
#define BOOST_HANA_DETAIL_OPERATORS_SEARCHABLE_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/fwd/at_key.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail {
|
||||
template <typename Derived>
|
||||
struct searchable_operators {
|
||||
template <typename Key>
|
||||
constexpr decltype(auto) operator[](Key&& key) & {
|
||||
return hana::at_key(static_cast<Derived&>(*this),
|
||||
static_cast<Key&&>(key));
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
constexpr decltype(auto) operator[](Key&& key) && {
|
||||
return hana::at_key(static_cast<Derived&&>(*this),
|
||||
static_cast<Key&&>(key));
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
constexpr decltype(auto) operator[](Key&& key) const& {
|
||||
return hana::at_key(static_cast<Derived const&>(*this),
|
||||
static_cast<Key&&>(key));
|
||||
}
|
||||
};
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_OPERATORS_SEARCHABLE_HPP
|
@ -0,0 +1,39 @@
|
||||
/*!
|
||||
@file
|
||||
Defines generally useful preprocessor macros.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_PREPROCESSOR_HPP
|
||||
#define BOOST_HANA_DETAIL_PREPROCESSOR_HPP
|
||||
|
||||
//! @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)
|
||||
#define BOOST_HANA_PP_CONCAT_PRIMITIVE(x, y) x ## y
|
||||
|
||||
//! @ingroup group-details
|
||||
//! Expands to the stringized version of its argument.
|
||||
#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 first argument.
|
||||
#ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
|
||||
#define BOOST_HANA_PP_FRONT(...) BOOST_HANA_PP_FRONT_IMPL_I(__VA_ARGS__)
|
||||
#define BOOST_HANA_PP_FRONT_IMPL_I(...) BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_FRONT_IMPL(__VA_ARGS__, ),)
|
||||
#else
|
||||
#define BOOST_HANA_PP_FRONT(...) BOOST_HANA_PP_FRONT_IMPL(__VA_ARGS__, )
|
||||
#endif
|
||||
#define BOOST_HANA_PP_FRONT_IMPL(e0, ...) e0
|
||||
|
||||
//! @ingroup group-details
|
||||
//! Expands to all of its arguments, except for the first one.
|
||||
//!
|
||||
//! This macro may not be called with less than 2 arguments.
|
||||
#define BOOST_HANA_PP_DROP_FRONT(e0, ...) __VA_ARGS__
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_PREPROCESSOR_HPP
|
@ -0,0 +1,36 @@
|
||||
/*!
|
||||
@file
|
||||
Defines a SFINAE-friendly version of `std::common_type`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_STD_COMMON_TYPE_HPP
|
||||
#define BOOST_HANA_DETAIL_STD_COMMON_TYPE_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail {
|
||||
//! @ingroup group-details
|
||||
//! Equivalent to `std::common_type`, except it is SFINAE-friendly and
|
||||
//! does not support custom specializations.
|
||||
template <typename T, typename U, typename = void>
|
||||
struct std_common_type { };
|
||||
|
||||
template <typename T, typename U>
|
||||
struct std_common_type<T, U, decltype((void)(
|
||||
true ? std::declval<T>() : std::declval<U>()
|
||||
))> {
|
||||
using type = typename detail::decay<
|
||||
decltype(true ? std::declval<T>() : std::declval<U>())
|
||||
>::type;
|
||||
};
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_STD_COMMON_TYPE_HPP
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,267 @@
|
||||
<%#
|
||||
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.hpp.erb
|
||||
|
||||
'MAX_NUMBER_OF_MEMBERS' must be greater than 0. In case 'MAX_NUMBER_OF_MEMBERS'
|
||||
is not specified, it defaults to 55. To regenerate the default struct macros,
|
||||
issue the following command from the root of the project:
|
||||
|
||||
erb include/boost/hana/detail/struct_macros.hpp.erb > include/boost/hana/detail/struct_macros.hpp
|
||||
|
||||
[1]: http://en.wikipedia.org/wiki/ERuby
|
||||
%>
|
||||
|
||||
<%
|
||||
MAX_NUMBER_OF_MEMBERS = (ENV["MAX_NUMBER_OF_MEMBERS"] || 55).to_i
|
||||
raise "MAX_NUMBER_OF_MEMBERS must be > 0" if not MAX_NUMBER_OF_MEMBERS > 0
|
||||
%>
|
||||
|
||||
/*!
|
||||
@file
|
||||
Defines the `BOOST_HANA_DEFINE_STRUCT`, `BOOST_HANA_ADAPT_STRUCT`, and
|
||||
`BOOST_HANA_ADAPT_ADT` macros.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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>
|
||||
|
||||
|
||||
namespace boost { namespace hana { 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>{});
|
||||
}
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// BOOST_HANA_PP_NARG
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//! @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
|
||||
//! an error to call this macro with 0 arguments.
|
||||
|
||||
#ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
|
||||
# define BOOST_HANA_PP_NARG(...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_NARG_IMPL(__VA_ARGS__, <%= (1..MAX_NUMBER_OF_MEMBERS).to_a.reverse.join(',') %>,),)
|
||||
#else
|
||||
# define BOOST_HANA_PP_NARG(...) \
|
||||
BOOST_HANA_PP_NARG_IMPL(__VA_ARGS__, <%= (1..MAX_NUMBER_OF_MEMBERS).to_a.reverse.join(',') %>,)
|
||||
#endif
|
||||
|
||||
#define BOOST_HANA_PP_NARG_IMPL(<%= (1..MAX_NUMBER_OF_MEMBERS).to_a.map { |i| "e#{i}" }.join(',') %>, N, ...) N
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// BOOST_HANA_PP_BACK
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//! @ingroup group-details
|
||||
//! Expands to its last argument.
|
||||
#define BOOST_HANA_PP_BACK(...) \
|
||||
BOOST_HANA_PP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)
|
||||
|
||||
#ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
|
||||
# define BOOST_HANA_PP_BACK_IMPL(N, ...) BOOST_HANA_PP_BACK_IMPL_I(N, __VA_ARGS__)
|
||||
# define BOOST_HANA_PP_BACK_IMPL_I(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_BACK_IMPL_, N)(__VA_ARGS__),)
|
||||
#else
|
||||
# define BOOST_HANA_PP_BACK_IMPL(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_BACK_IMPL_, N)(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
<% (1..MAX_NUMBER_OF_MEMBERS).each do |n| %>
|
||||
#define BOOST_HANA_PP_BACK_IMPL_<%= n %>(<%= (1..n).to_a.map { |i| "e#{i}" }.join(', ') %>) e<%= n %>
|
||||
<% end %>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// BOOST_HANA_PP_DROP_BACK
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//! @ingroup group-details
|
||||
//! Expands to all of its arguments, except for the last one.
|
||||
#define BOOST_HANA_PP_DROP_BACK(...) \
|
||||
BOOST_HANA_PP_DROP_BACK_IMPL(BOOST_HANA_PP_NARG(__VA_ARGS__), __VA_ARGS__)
|
||||
|
||||
#ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
|
||||
# define BOOST_HANA_PP_DROP_BACK_IMPL(N, ...) BOOST_HANA_PP_DROP_BACK_IMPL_I(N, __VA_ARGS__)
|
||||
# define BOOST_HANA_PP_DROP_BACK_IMPL_I(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_DROP_BACK_IMPL_, N)(__VA_ARGS__),)
|
||||
#else
|
||||
# define BOOST_HANA_PP_DROP_BACK_IMPL(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_DROP_BACK_IMPL_, N)(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
<% (1..MAX_NUMBER_OF_MEMBERS).each do |n| %>
|
||||
#define BOOST_HANA_PP_DROP_BACK_IMPL_<%= n %>(<%= (1..n).to_a.map { |i| "e#{i}" }.join(', ') %>)<%= (1..n-1).to_a.map { |i| "e#{i}" }.join(', ') %>
|
||||
<% 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") \
|
||||
/**/
|
||||
|
||||
#ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
|
||||
# define BOOST_HANA_ADAPT_STRUCT_IMPL(N, ...) BOOST_HANA_ADAPT_STRUCT_IMPL_I(N, __VA_ARGS__)
|
||||
# define BOOST_HANA_ADAPT_STRUCT_IMPL_I(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_STRUCT_IMPL_, N)(__VA_ARGS__),)
|
||||
#else
|
||||
# define BOOST_HANA_ADAPT_STRUCT_IMPL(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_STRUCT_IMPL_, N)(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
<% (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") \
|
||||
/**/
|
||||
|
||||
#ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
|
||||
# define BOOST_HANA_ADAPT_ADT_IMPL(N, ...) BOOST_HANA_ADAPT_ADT_IMPL_I(N, __VA_ARGS__)
|
||||
# define BOOST_HANA_ADAPT_ADT_IMPL_I(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_ADT_IMPL_, N)(__VA_ARGS__),)
|
||||
#else
|
||||
# define BOOST_HANA_ADAPT_ADT_IMPL(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_ADAPT_ADT_IMPL_, N)(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
<% (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__)
|
||||
|
||||
#ifdef BOOST_HANA_WORKAROUND_MSVC_PREPROCESSOR_616033
|
||||
# define BOOST_HANA_DEFINE_STRUCT_IMPL(N, ...) BOOST_HANA_DEFINE_STRUCT_IMPL_I(N, __VA_ARGS__)
|
||||
# define BOOST_HANA_DEFINE_STRUCT_IMPL_I(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_PP_CONCAT(BOOST_HANA_DEFINE_STRUCT_IMPL_, N)(__VA_ARGS__),)
|
||||
#else
|
||||
# define BOOST_HANA_DEFINE_STRUCT_IMPL(N, ...) \
|
||||
BOOST_HANA_PP_CONCAT(BOOST_HANA_DEFINE_STRUCT_IMPL_, N)(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
<% (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
|
@ -0,0 +1,57 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::type_at`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_TYPE_AT_HPP
|
||||
#define BOOST_HANA_DETAIL_TYPE_AT_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
// If possible, use an intrinsic provided by Clang
|
||||
#if defined(__has_builtin)
|
||||
# if __has_builtin(__type_pack_element)
|
||||
# define BOOST_HANA_USE_TYPE_PACK_ELEMENT_INTRINSIC
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace boost { namespace hana { namespace detail {
|
||||
namespace td {
|
||||
template <std::size_t I, typename T>
|
||||
struct elt { using type = T; };
|
||||
|
||||
template <typename Indices, typename ...T>
|
||||
struct indexer;
|
||||
|
||||
template <std::size_t ...I, typename ...T>
|
||||
struct indexer<std::index_sequence<I...>, T...>
|
||||
: elt<I, T>...
|
||||
{ };
|
||||
|
||||
template <std::size_t I, typename T>
|
||||
elt<I, T> get_elt(elt<I, T> const&);
|
||||
}
|
||||
|
||||
//! @ingroup group-details
|
||||
//! Classic MPL-style metafunction returning the nth element of a type
|
||||
//! parameter pack.
|
||||
template <std::size_t n, typename ...T>
|
||||
struct type_at {
|
||||
#if defined(BOOST_HANA_USE_TYPE_PACK_ELEMENT_INTRINSIC)
|
||||
using type = __type_pack_element<n, T...>;
|
||||
#else
|
||||
using Indexer = td::indexer<std::make_index_sequence<sizeof...(T)>, T...>;
|
||||
using type = typename decltype(td::get_elt<n>(Indexer{}))::type;
|
||||
#endif
|
||||
};
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_TYPE_AT_HPP
|
@ -0,0 +1,145 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::type_foldl1`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_TYPE_FOLDL1_HPP
|
||||
#define BOOST_HANA_DETAIL_TYPE_FOLDL1_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail {
|
||||
template <unsigned n>
|
||||
struct type_foldl1_t;
|
||||
|
||||
template <>
|
||||
struct type_foldl1_t<0> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename state
|
||||
>
|
||||
using result = state;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldl1_t<1> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename state,
|
||||
typename x1
|
||||
>
|
||||
using result = typename f<state, x1>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldl1_t<2> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename state,
|
||||
typename x1, typename x2
|
||||
>
|
||||
using result = typename f<typename f<state, x1>::type, x2>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldl1_t<3> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename state,
|
||||
typename x1, typename x2, typename x3
|
||||
>
|
||||
using result = typename f<
|
||||
typename f<
|
||||
typename f<state, x1>::type,
|
||||
x2
|
||||
>::type,
|
||||
x3
|
||||
>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldl1_t<4> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename state,
|
||||
typename x1, typename x2, typename x3, typename x4
|
||||
>
|
||||
using result = typename f<
|
||||
typename f<
|
||||
typename f<
|
||||
typename f<state, x1>::type,
|
||||
x2
|
||||
>::type,
|
||||
x3
|
||||
>::type,
|
||||
x4
|
||||
>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldl1_t<5> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename state,
|
||||
typename x1, typename x2, typename x3, typename x4, typename x5
|
||||
>
|
||||
using result = typename f<
|
||||
typename f<
|
||||
typename f<
|
||||
typename f<
|
||||
typename f<state, x1>::type,
|
||||
x2
|
||||
>::type,
|
||||
x3
|
||||
>::type,
|
||||
x4
|
||||
>::type,
|
||||
x5
|
||||
>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldl1_t<6> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename state,
|
||||
typename x1, typename x2, typename x3, typename x4, typename x5, typename x6,
|
||||
typename ...xs
|
||||
>
|
||||
using result =
|
||||
typename type_foldl1_t<(sizeof...(xs) > 6 ? 6 : sizeof...(xs))>::
|
||||
template result<
|
||||
f,
|
||||
typename f<
|
||||
typename f<
|
||||
typename f<
|
||||
typename f<
|
||||
typename f<
|
||||
typename f<state, x1>::type,
|
||||
x2
|
||||
>::type,
|
||||
x3
|
||||
>::type,
|
||||
x4
|
||||
>::type,
|
||||
x5
|
||||
>::type,
|
||||
x6
|
||||
>::type,
|
||||
xs...
|
||||
>;
|
||||
};
|
||||
|
||||
template <template <typename ...> class f, typename x1, typename ...xn>
|
||||
struct type_foldl1 {
|
||||
using type = typename type_foldl1_t<(sizeof...(xn) > 6 ? 6 : sizeof...(xn))>
|
||||
::template result<f, x1, xn...>;
|
||||
};
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_TYPE_FOLDL1_HPP
|
@ -0,0 +1,149 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::type_foldr1`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_TYPE_FOLDR1_HPP
|
||||
#define BOOST_HANA_DETAIL_TYPE_FOLDR1_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail {
|
||||
template <unsigned n>
|
||||
struct type_foldr1_t;
|
||||
|
||||
template <>
|
||||
struct type_foldr1_t<0> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename state
|
||||
>
|
||||
using result = state;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldr1_t<1> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename x1,
|
||||
typename state
|
||||
>
|
||||
using result = typename f<x1, state>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldr1_t<2> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename x1, typename x2,
|
||||
typename state
|
||||
>
|
||||
using result = typename f<x1, typename f<x2, state>::type>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldr1_t<3> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename x1, typename x2, typename x3,
|
||||
typename state
|
||||
>
|
||||
using result = typename f<
|
||||
x1,
|
||||
typename f<
|
||||
x2,
|
||||
typename f<
|
||||
x3,
|
||||
state
|
||||
>::type
|
||||
>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldr1_t<4> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename x1, typename x2, typename x3, typename x4,
|
||||
typename state
|
||||
>
|
||||
using result = typename f<
|
||||
x1,
|
||||
typename f<
|
||||
x2,
|
||||
typename f<
|
||||
x3,
|
||||
typename f<
|
||||
x4,
|
||||
state
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldr1_t<5> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename x1, typename x2, typename x3, typename x4, typename x5,
|
||||
typename state
|
||||
>
|
||||
using result = typename f<
|
||||
x1,
|
||||
typename f<
|
||||
x2,
|
||||
typename f<
|
||||
x3,
|
||||
typename f<
|
||||
x4,
|
||||
typename f<
|
||||
x5,
|
||||
state
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct type_foldr1_t<6> {
|
||||
template <
|
||||
template <typename ...> class f,
|
||||
typename x1, typename x2, typename x3, typename x4, typename x5, typename x6,
|
||||
typename ...xs
|
||||
>
|
||||
using result =
|
||||
typename f<
|
||||
x1,
|
||||
typename f<
|
||||
x2,
|
||||
typename f<
|
||||
x3,
|
||||
typename f<
|
||||
x4,
|
||||
typename f<
|
||||
x5,
|
||||
typename type_foldr1_t<(sizeof...(xs) > 6 ? 6 : sizeof...(xs))>::
|
||||
template result<f, x6, xs...>
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type;
|
||||
};
|
||||
|
||||
template <template <typename ...> class f, typename x1, typename ...xn>
|
||||
struct type_foldr1 {
|
||||
using type = typename type_foldr1_t<(sizeof...(xn) > 6 ? 6 : sizeof...(xn))>
|
||||
::template result<f, x1, xn...>;
|
||||
};
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_TYPE_FOLDR1_HPP
|
@ -0,0 +1,70 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::unpack_flatten`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_UNPACK_FLATTEN_HPP
|
||||
#define BOOST_HANA_DETAIL_UNPACK_FLATTEN_HPP
|
||||
|
||||
#include <boost/hana/at.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/algorithm.hpp>
|
||||
#include <boost/hana/detail/array.hpp>
|
||||
#include <boost/hana/length.hpp>
|
||||
#include <boost/hana/unpack.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail {
|
||||
template <std::size_t ...Lengths>
|
||||
struct flatten_indices {
|
||||
// avoid empty arrays by appending 0 to `lengths`
|
||||
static constexpr std::size_t lengths[sizeof...(Lengths) + 1] = {Lengths..., 0};
|
||||
static constexpr auto flat_length =
|
||||
detail::accumulate(lengths, lengths + sizeof...(Lengths), 0);
|
||||
|
||||
template <bool Inner>
|
||||
static constexpr auto compute() {
|
||||
detail::array<std::size_t, flat_length> indices{};
|
||||
for (std::size_t index = 0, i = 0; i < sizeof...(Lengths); ++i)
|
||||
for (std::size_t j = 0; j < lengths[i]; ++j, ++index)
|
||||
indices[index] = (Inner ? i : j);
|
||||
return indices;
|
||||
}
|
||||
|
||||
static constexpr auto inner = compute<true>();
|
||||
static constexpr auto outer = compute<false>();
|
||||
|
||||
template <typename Xs, typename F, std::size_t ...i>
|
||||
static constexpr decltype(auto)
|
||||
apply(Xs&& xs, F&& f, std::index_sequence<i...>) {
|
||||
return static_cast<F&&>(f)(
|
||||
hana::at_c<outer[i]>(hana::at_c<inner[i]>(
|
||||
static_cast<Xs&&>(xs)
|
||||
))...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct make_flatten_indices {
|
||||
template <typename ...Xs>
|
||||
auto operator()(Xs const& ...xs) const -> detail::flatten_indices<
|
||||
decltype(hana::length(xs))::value...
|
||||
>;
|
||||
};
|
||||
|
||||
template <typename Xs, typename F>
|
||||
constexpr decltype(auto) unpack_flatten(Xs&& xs, F&& f) {
|
||||
using Indices = decltype(hana::unpack(xs, make_flatten_indices{}));
|
||||
return Indices::apply(static_cast<Xs&&>(xs), static_cast<F&&>(f),
|
||||
std::make_index_sequence<Indices::flat_length>{});
|
||||
}
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_UNPACK_FLATTEN_HPP
|
@ -0,0 +1,40 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::variadic::at`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VARIADIC_AT_HPP
|
||||
#define BOOST_HANA_DETAIL_VARIADIC_AT_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail { namespace variadic {
|
||||
template <std::size_t n, typename = std::make_index_sequence<n>>
|
||||
struct at_type;
|
||||
|
||||
template <std::size_t n, std::size_t ...ignore>
|
||||
struct at_type<n, std::index_sequence<ignore...>> {
|
||||
private:
|
||||
template <typename Nth>
|
||||
static constexpr auto go(decltype(ignore, (void*)0)..., Nth nth, ...)
|
||||
{ return nth; }
|
||||
|
||||
public:
|
||||
template <typename ...Xs>
|
||||
constexpr auto operator()(Xs ...xs) const
|
||||
{ return *go(&xs...); }
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr at_type<n> at{};
|
||||
}} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VARIADIC_AT_HPP
|
@ -0,0 +1,47 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::variadic::drop_into`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VARIADIC_DROP_INTO_HPP
|
||||
#define BOOST_HANA_DETAIL_VARIADIC_DROP_INTO_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail { namespace variadic {
|
||||
template <std::size_t n, typename F, typename = std::make_index_sequence<n>>
|
||||
struct dropper;
|
||||
|
||||
template <std::size_t n, typename F, std::size_t ...ignore>
|
||||
struct dropper<n, F, std::index_sequence<ignore...>> {
|
||||
F f;
|
||||
|
||||
template <typename ...Rest>
|
||||
constexpr auto go(decltype(ignore, (void*)0)..., Rest ...rest) const
|
||||
{ return f(*rest...); }
|
||||
|
||||
template <typename ...Xs>
|
||||
constexpr auto operator()(Xs ...xs) const
|
||||
{ return go(&xs...); }
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
struct make_dropper {
|
||||
template <typename F>
|
||||
constexpr auto operator()(F f) const
|
||||
{ return dropper<n, decltype(f)>{f}; }
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_dropper<n> drop_into{};
|
||||
}} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VARIADIC_DROP_INTO_HPP
|
@ -0,0 +1,214 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::variadic::foldl1`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VARIADIC_FOLDL1_HPP
|
||||
#define BOOST_HANA_DETAIL_VARIADIC_FOLDL1_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail { namespace variadic {
|
||||
//! @cond
|
||||
template <unsigned int n, typename = when<true>>
|
||||
struct foldl1_impl;
|
||||
|
||||
template <>
|
||||
struct foldl1_impl<1> {
|
||||
template <typename F, typename X1>
|
||||
static constexpr X1 apply(F&&, X1&& x1)
|
||||
{ return static_cast<X1&&>(x1); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldl1_impl<2> {
|
||||
template <typename F, typename X1, typename X2>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2) {
|
||||
return static_cast<F&&>(f)(static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldl1_impl<3> {
|
||||
template <typename F, typename X1, typename X2, typename X3>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3) {
|
||||
return f(f(static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2)),
|
||||
static_cast<X3&&>(x3));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldl1_impl<4> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4) {
|
||||
return f(f(f(static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2)),
|
||||
static_cast<X3&&>(x3)),
|
||||
static_cast<X4&&>(x4));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldl1_impl<5> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5) {
|
||||
return f(f(f(f(static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2)),
|
||||
static_cast<X3&&>(x3)),
|
||||
static_cast<X4&&>(x4)),
|
||||
static_cast<X5&&>(x5));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldl1_impl<6> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6) {
|
||||
return f(f(f(f(f(static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2)),
|
||||
static_cast<X3&&>(x3)),
|
||||
static_cast<X4&&>(x4)),
|
||||
static_cast<X5&&>(x5)),
|
||||
static_cast<X6&&>(x6));
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int n>
|
||||
struct foldl1_impl<n, when<(n >= 7) && (n < 14)>> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename ...Xn>
|
||||
static constexpr decltype(auto)
|
||||
apply(F&& f
|
||||
, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
|
||||
, Xn&& ...xn)
|
||||
{
|
||||
return foldl1_impl<sizeof...(xn) + 1>::apply(
|
||||
f,
|
||||
f(f(f(f(f(f(static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2)),
|
||||
static_cast<X3&&>(x3)),
|
||||
static_cast<X4&&>(x4)),
|
||||
static_cast<X5&&>(x5)),
|
||||
static_cast<X6&&>(x6)),
|
||||
static_cast<X7&&>(x7)),
|
||||
static_cast<Xn&&>(xn)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int n>
|
||||
struct foldl1_impl<n, when<(n >= 14) && (n < 28)>> {
|
||||
template <
|
||||
typename F
|
||||
, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7
|
||||
, typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
|
||||
, typename ...Xn
|
||||
>
|
||||
static constexpr decltype(auto)
|
||||
apply(F&& f
|
||||
, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
|
||||
, X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
|
||||
, Xn&& ...xn)
|
||||
{
|
||||
return foldl1_impl<sizeof...(xn) + 1>::apply(
|
||||
f,
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
static_cast<X1&&>(x1), static_cast<X2&&>(x2)), static_cast<X3&&>(x3)), static_cast<X4&&>(x4)), static_cast<X5&&>(x5)), static_cast<X6&&>(x6)), static_cast<X7&&>(x7)),
|
||||
static_cast<X8&&>(x8)), static_cast<X9&&>(x9)), static_cast<X10&&>(x10)), static_cast<X11&&>(x11)), static_cast<X12&&>(x12)), static_cast<X13&&>(x13)), static_cast<X14&&>(x14))
|
||||
, static_cast<Xn&&>(xn)...);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int n>
|
||||
struct foldl1_impl<n, when<(n >= 28) && (n < 56)>> {
|
||||
template <
|
||||
typename F
|
||||
, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7
|
||||
, typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
|
||||
, typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21
|
||||
, typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28
|
||||
, typename ...Xn
|
||||
>
|
||||
static constexpr decltype(auto)
|
||||
apply(F&& f
|
||||
, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
|
||||
, X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
|
||||
, X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21
|
||||
, X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28
|
||||
, Xn&& ...xn)
|
||||
{
|
||||
return foldl1_impl<sizeof...(xn) + 1>::apply(
|
||||
f,
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
static_cast<X1&&>(x1), static_cast<X2&&>(x2)), static_cast<X3&&>(x3)), static_cast<X4&&>(x4)), static_cast<X5&&>(x5)), static_cast<X6&&>(x6)), static_cast<X7&&>(x7)),
|
||||
static_cast<X8&&>(x8)), static_cast<X9&&>(x9)), static_cast<X10&&>(x10)), static_cast<X11&&>(x11)), static_cast<X12&&>(x12)), static_cast<X13&&>(x13)), static_cast<X14&&>(x14)),
|
||||
static_cast<X15&&>(x15)), static_cast<X16&&>(x16)), static_cast<X17&&>(x17)), static_cast<X18&&>(x18)), static_cast<X19&&>(x19)), static_cast<X20&&>(x20)), static_cast<X21&&>(x21)),
|
||||
static_cast<X22&&>(x22)), static_cast<X23&&>(x23)), static_cast<X24&&>(x24)), static_cast<X25&&>(x25)), static_cast<X26&&>(x26)), static_cast<X27&&>(x27)), static_cast<X28&&>(x28))
|
||||
, static_cast<Xn&&>(xn)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int n>
|
||||
struct foldl1_impl<n, when<(n >= 56)>> {
|
||||
template <
|
||||
typename F
|
||||
, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7
|
||||
, typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
|
||||
, typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21
|
||||
, typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28
|
||||
, typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35
|
||||
, typename X36, typename X37, typename X38, typename X39, typename X40, typename X41, typename X42
|
||||
, typename X43, typename X44, typename X45, typename X46, typename X47, typename X48, typename X49
|
||||
, typename X50, typename X51, typename X52, typename X53, typename X54, typename X55, typename X56
|
||||
, typename ...Xn
|
||||
>
|
||||
static constexpr decltype(auto)
|
||||
apply(F&& f
|
||||
, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
|
||||
, X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
|
||||
, X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21
|
||||
, X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28
|
||||
, X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35
|
||||
, X36&& x36, X37&& x37, X38&& x38, X39&& x39, X40&& x40, X41&& x41, X42&& x42
|
||||
, X43&& x43, X44&& x44, X45&& x45, X46&& x46, X47&& x47, X48&& x48, X49&& x49
|
||||
, X50&& x50, X51&& x51, X52&& x52, X53&& x53, X54&& x54, X55&& x55, X56&& x56
|
||||
, Xn&& ...xn)
|
||||
{
|
||||
return foldl1_impl<sizeof...(xn) + 1>::apply(
|
||||
f,
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
static_cast<X1&&>(x1), static_cast<X2&&>(x2)), static_cast<X3&&>(x3)), static_cast<X4&&>(x4)), static_cast<X5&&>(x5)), static_cast<X6&&>(x6)), static_cast<X7&&>(x7)),
|
||||
static_cast<X8&&>(x8)), static_cast<X9&&>(x9)), static_cast<X10&&>(x10)), static_cast<X11&&>(x11)), static_cast<X12&&>(x12)), static_cast<X13&&>(x13)), static_cast<X14&&>(x14)),
|
||||
static_cast<X15&&>(x15)), static_cast<X16&&>(x16)), static_cast<X17&&>(x17)), static_cast<X18&&>(x18)), static_cast<X19&&>(x19)), static_cast<X20&&>(x20)), static_cast<X21&&>(x21)),
|
||||
static_cast<X22&&>(x22)), static_cast<X23&&>(x23)), static_cast<X24&&>(x24)), static_cast<X25&&>(x25)), static_cast<X26&&>(x26)), static_cast<X27&&>(x27)), static_cast<X28&&>(x28)),
|
||||
static_cast<X29&&>(x29)), static_cast<X30&&>(x30)), static_cast<X31&&>(x31)), static_cast<X32&&>(x32)), static_cast<X33&&>(x33)), static_cast<X34&&>(x34)), static_cast<X35&&>(x35)),
|
||||
static_cast<X36&&>(x36)), static_cast<X37&&>(x37)), static_cast<X38&&>(x38)), static_cast<X39&&>(x39)), static_cast<X40&&>(x40)), static_cast<X41&&>(x41)), static_cast<X42&&>(x42)),
|
||||
static_cast<X43&&>(x43)), static_cast<X44&&>(x44)), static_cast<X45&&>(x45)), static_cast<X46&&>(x46)), static_cast<X47&&>(x47)), static_cast<X48&&>(x48)), static_cast<X49&&>(x49)),
|
||||
static_cast<X50&&>(x50)), static_cast<X51&&>(x51)), static_cast<X52&&>(x52)), static_cast<X53&&>(x53)), static_cast<X54&&>(x54)), static_cast<X55&&>(x55)), static_cast<X56&&>(x56))
|
||||
, static_cast<Xn&&>(xn)...);
|
||||
}
|
||||
};
|
||||
//! @endcond
|
||||
|
||||
struct foldl1_t {
|
||||
template <typename F, typename X1, typename ...Xn>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, Xn&& ...xn) const {
|
||||
return foldl1_impl<sizeof...(xn) + 1>::apply(
|
||||
static_cast<F&&>(f), static_cast<X1&&>(x1), static_cast<Xn&&>(xn)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr foldl1_t foldl1{};
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr auto foldl = foldl1;
|
||||
}} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VARIADIC_FOLDL1_HPP
|
@ -0,0 +1,210 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::variadic::foldr1`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VARIADIC_FOLDR1_HPP
|
||||
#define BOOST_HANA_DETAIL_VARIADIC_FOLDR1_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail { namespace variadic {
|
||||
//! @cond
|
||||
template <unsigned int n, typename = when<true>>
|
||||
struct foldr1_impl;
|
||||
|
||||
template <>
|
||||
struct foldr1_impl<1> {
|
||||
template <typename F, typename X1>
|
||||
static constexpr X1 apply(F&&, X1&& x1)
|
||||
{ return static_cast<X1&&>(x1); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldr1_impl<2> {
|
||||
template <typename F, typename X1, typename X2>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2) {
|
||||
return static_cast<F&&>(f)(static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldr1_impl<3> {
|
||||
template <typename F, typename X1, typename X2, typename X3>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3) {
|
||||
return f(static_cast<X1&&>(x1),
|
||||
f(static_cast<X2&&>(x2),
|
||||
static_cast<X3&&>(x3)));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldr1_impl<4> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4) {
|
||||
return f(static_cast<X1&&>(x1),
|
||||
f(static_cast<X2&&>(x2),
|
||||
f(static_cast<X3&&>(x3),
|
||||
static_cast<X4&&>(x4))));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldr1_impl<5> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5) {
|
||||
return f(static_cast<X1&&>(x1),
|
||||
f(static_cast<X2&&>(x2),
|
||||
f(static_cast<X3&&>(x3),
|
||||
f(static_cast<X4&&>(x4),
|
||||
static_cast<X5&&>(x5)))));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct foldr1_impl<6> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6>
|
||||
static constexpr decltype(auto) apply(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6) {
|
||||
return f(static_cast<X1&&>(x1),
|
||||
f(static_cast<X2&&>(x2),
|
||||
f(static_cast<X3&&>(x3),
|
||||
f(static_cast<X4&&>(x4),
|
||||
f(static_cast<X5&&>(x5),
|
||||
static_cast<X6&&>(x6))))));
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int n>
|
||||
struct foldr1_impl<n, when<(n >= 7) && (n < 14)>> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename ...Xn>
|
||||
static constexpr decltype(auto)
|
||||
apply(F&& f
|
||||
, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
|
||||
, Xn&& ...xn)
|
||||
{
|
||||
return f(static_cast<X1&&>(x1),
|
||||
f(static_cast<X2&&>(x2),
|
||||
f(static_cast<X3&&>(x3),
|
||||
f(static_cast<X4&&>(x4),
|
||||
f(static_cast<X5&&>(x5),
|
||||
f(static_cast<X6&&>(x6),
|
||||
foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X7&&>(x7), static_cast<Xn&&>(xn)...)))))));
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int n>
|
||||
struct foldr1_impl<n, when<(n >= 14) && (n < 28)>> {
|
||||
template <
|
||||
typename F
|
||||
, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7
|
||||
, typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
|
||||
, typename ...Xn
|
||||
>
|
||||
static constexpr decltype(auto)
|
||||
apply(F&& f
|
||||
, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
|
||||
, X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
|
||||
, Xn&& ...xn)
|
||||
{
|
||||
return f(static_cast<X1&&>(x1), f(static_cast<X2&&>(x2), f(static_cast<X3&&>(x3), f(static_cast<X4&&>(x4), f(static_cast<X5&&>(x5), f(static_cast<X6&&>(x6), f(static_cast<X7&&>(x7),
|
||||
f(static_cast<X8&&>(x8), f(static_cast<X9&&>(x9), f(static_cast<X10&&>(x10), f(static_cast<X11&&>(x11), f(static_cast<X12&&>(x12), f(static_cast<X13&&>(x13),
|
||||
foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X14&&>(x14), static_cast<Xn&&>(xn)...))))))))))))));
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int n>
|
||||
struct foldr1_impl<n, when<(n >= 28) && (n < 56)>> {
|
||||
template <
|
||||
typename F
|
||||
, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7
|
||||
, typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
|
||||
, typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21
|
||||
, typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28
|
||||
, typename ...Xn
|
||||
>
|
||||
static constexpr decltype(auto)
|
||||
apply(F&& f
|
||||
, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
|
||||
, X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
|
||||
, X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21
|
||||
, X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28
|
||||
, Xn&& ...xn)
|
||||
{
|
||||
return f(static_cast<X1&&>(x1), f(static_cast<X2&&>(x2), f(static_cast<X3&&>(x3), f(static_cast<X4&&>(x4), f(static_cast<X5&&>(x5), f(static_cast<X6&&>(x6), f(static_cast<X7&&>(x7),
|
||||
f(static_cast<X8&&>(x8), f(static_cast<X9&&>(x9), f(static_cast<X10&&>(x10), f(static_cast<X11&&>(x11), f(static_cast<X12&&>(x12), f(static_cast<X13&&>(x13), f(static_cast<X14&&>(x14),
|
||||
f(static_cast<X15&&>(x15), f(static_cast<X16&&>(x16), f(static_cast<X17&&>(x17), f(static_cast<X18&&>(x18), f(static_cast<X19&&>(x19), f(static_cast<X20&&>(x20), f(static_cast<X21&&>(x21),
|
||||
f(static_cast<X22&&>(x22), f(static_cast<X23&&>(x23), f(static_cast<X24&&>(x24), f(static_cast<X25&&>(x25), f(static_cast<X26&&>(x26), f(static_cast<X27&&>(x27),
|
||||
foldr1_impl<sizeof...(xn) + 1>::apply(f, static_cast<X28&&>(x28), static_cast<Xn&&>(xn)...))))))))))))))))))))))))))));
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned int n>
|
||||
struct foldr1_impl<n, when<(n >= 56)>> {
|
||||
template <
|
||||
typename F
|
||||
, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7
|
||||
, typename X8, typename X9, typename X10, typename X11, typename X12, typename X13, typename X14
|
||||
, typename X15, typename X16, typename X17, typename X18, typename X19, typename X20, typename X21
|
||||
, typename X22, typename X23, typename X24, typename X25, typename X26, typename X27, typename X28
|
||||
, typename X29, typename X30, typename X31, typename X32, typename X33, typename X34, typename X35
|
||||
, typename X36, typename X37, typename X38, typename X39, typename X40, typename X41, typename X42
|
||||
, typename X43, typename X44, typename X45, typename X46, typename X47, typename X48, typename X49
|
||||
, typename X50, typename X51, typename X52, typename X53, typename X54, typename X55, typename X56
|
||||
, typename ...Xn
|
||||
>
|
||||
static constexpr decltype(auto)
|
||||
apply(F&& f
|
||||
, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7
|
||||
, X8&& x8, X9&& x9, X10&& x10, X11&& x11, X12&& x12, X13&& x13, X14&& x14
|
||||
, X15&& x15, X16&& x16, X17&& x17, X18&& x18, X19&& x19, X20&& x20, X21&& x21
|
||||
, X22&& x22, X23&& x23, X24&& x24, X25&& x25, X26&& x26, X27&& x27, X28&& x28
|
||||
, X29&& x29, X30&& x30, X31&& x31, X32&& x32, X33&& x33, X34&& x34, X35&& x35
|
||||
, X36&& x36, X37&& x37, X38&& x38, X39&& x39, X40&& x40, X41&& x41, X42&& x42
|
||||
, X43&& x43, X44&& x44, X45&& x45, X46&& x46, X47&& x47, X48&& x48, X49&& x49
|
||||
, X50&& x50, X51&& x51, X52&& x52, X53&& x53, X54&& x54, X55&& x55, X56&& x56
|
||||
, Xn&& ...xn)
|
||||
{
|
||||
return f(static_cast<X1&&>(x1), f(static_cast<X2&&>(x2), f(static_cast<X3&&>(x3), f(static_cast<X4&&>(x4), f(static_cast<X5&&>(x5), f(static_cast<X6&&>(x6), f(static_cast<X7&&>(x7),
|
||||
f(static_cast<X8&&>(x8), f(static_cast<X9&&>(x9), f(static_cast<X10&&>(x10), f(static_cast<X11&&>(x11), f(static_cast<X12&&>(x12), f(static_cast<X13&&>(x13), f(static_cast<X14&&>(x14),
|
||||
f(static_cast<X15&&>(x15), f(static_cast<X16&&>(x16), f(static_cast<X17&&>(x17), f(static_cast<X18&&>(x18), f(static_cast<X19&&>(x19), f(static_cast<X20&&>(x20), f(static_cast<X21&&>(x21),
|
||||
f(static_cast<X22&&>(x22), f(static_cast<X23&&>(x23), f(static_cast<X24&&>(x24), f(static_cast<X25&&>(x25), f(static_cast<X26&&>(x26), f(static_cast<X27&&>(x27), f(static_cast<X28&&>(x28),
|
||||
f(static_cast<X29&&>(x29), f(static_cast<X30&&>(x30), f(static_cast<X31&&>(x31), f(static_cast<X32&&>(x32), f(static_cast<X33&&>(x33), f(static_cast<X34&&>(x34), f(static_cast<X35&&>(x35),
|
||||
f(static_cast<X36&&>(x36), f(static_cast<X37&&>(x37), f(static_cast<X38&&>(x38), f(static_cast<X39&&>(x39), f(static_cast<X40&&>(x40), f(static_cast<X41&&>(x41), f(static_cast<X42&&>(x42),
|
||||
f(static_cast<X43&&>(x43), f(static_cast<X44&&>(x44), f(static_cast<X45&&>(x45), f(static_cast<X46&&>(x46), f(static_cast<X47&&>(x47), f(static_cast<X48&&>(x48), f(static_cast<X49&&>(x49),
|
||||
f(static_cast<X50&&>(x50), f(static_cast<X51&&>(x51), f(static_cast<X52&&>(x52), f(static_cast<X53&&>(x53), f(static_cast<X54&&>(x54), f(static_cast<X55&&>(x55),
|
||||
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>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, Xn&& ...xn) const {
|
||||
return foldr1_impl<sizeof...(xn) + 1>::apply(
|
||||
static_cast<F&&>(f), static_cast<X1&&>(x1), static_cast<Xn&&>(xn)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr foldr1_t foldr1{};
|
||||
|
||||
struct foldr_t {
|
||||
template <typename F, typename State, typename ...Xn>
|
||||
constexpr decltype(auto) operator()(F&& f, State&& state, Xn&& ...xn) const {
|
||||
return foldr1_impl<sizeof...(xn) + 1>::apply(
|
||||
static_cast<F&&>(f), static_cast<Xn&&>(xn)..., static_cast<State&&>(state)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr foldr_t foldr{};
|
||||
}} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VARIADIC_FOLDR1_HPP
|
@ -0,0 +1,27 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::variadic::reverse_apply`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VARIADIC_REVERSE_APPLY_HPP
|
||||
#define BOOST_HANA_DETAIL_VARIADIC_REVERSE_APPLY_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/variadic/reverse_apply/unrolled.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail { namespace variadic {
|
||||
BOOST_HANA_INLINE_VARIABLE BOOST_HANA_CONSTEXPR_LAMBDA auto reverse_apply =
|
||||
[](auto&& f, auto&& ...x) -> decltype(auto) {
|
||||
return detail::variadic::reverse_apply_unrolled(
|
||||
static_cast<decltype(f)>(f),
|
||||
static_cast<decltype(x)>(x)...
|
||||
);
|
||||
};
|
||||
}} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VARIADIC_REVERSE_APPLY_HPP
|
@ -0,0 +1,41 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::variadic::reverse_apply_flat`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VARIADIC_REVERSE_APPLY_FLAT_HPP
|
||||
#define BOOST_HANA_DETAIL_VARIADIC_REVERSE_APPLY_FLAT_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/variadic/at.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail { namespace variadic {
|
||||
template <int ...i, typename F, typename ...X>
|
||||
constexpr decltype(auto)
|
||||
reverse_apply_flat_helper(std::integer_sequence<int, i...>, F&& f, X&& ...x)
|
||||
{
|
||||
return static_cast<F&&>(f)(
|
||||
detail::variadic::at<sizeof...(x) - i - 1>(
|
||||
static_cast<X&&>(x)...
|
||||
)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename F, typename ...X>
|
||||
constexpr decltype(auto) reverse_apply_flat(F&& f, X&& ...x) {
|
||||
return reverse_apply_flat_helper(
|
||||
std::make_integer_sequence<int, sizeof...(x)>{},
|
||||
static_cast<F&&>(f),
|
||||
static_cast<X&&>(x)...
|
||||
);
|
||||
}
|
||||
}} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VARIADIC_REVERSE_APPLY_FLAT_HPP
|
@ -0,0 +1,86 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::variadic::reverse_apply_unrolled`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VARIADIC_REVERSE_APPLY_UNROLLED_HPP
|
||||
#define BOOST_HANA_DETAIL_VARIADIC_REVERSE_APPLY_UNROLLED_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/functional/reverse_partial.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail { namespace variadic {
|
||||
struct reverse_apply_unrolled_impl {
|
||||
template <typename F>
|
||||
constexpr decltype(auto) operator()(F&& f) const {
|
||||
return static_cast<F&&>(f)();
|
||||
}
|
||||
|
||||
template <typename F, typename X1>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X1&&>(x1)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename F, typename X1, typename X2>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X1&&>(x1)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename F, typename X1, typename X2, typename X3>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X3&&>(x3),
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X1&&>(x1)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X4&&>(x4),
|
||||
static_cast<X3&&>(x3),
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X1&&>(x1)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X5&&>(x5),
|
||||
static_cast<X4&&>(x4),
|
||||
static_cast<X3&&>(x3),
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X1&&>(x1)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename ...Xn>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, Xn&& ...xn) const {
|
||||
return (*this)(hana::reverse_partial(
|
||||
static_cast<F&&>(f)
|
||||
, static_cast<X6&&>(x6)
|
||||
, static_cast<X5&&>(x5)
|
||||
, static_cast<X4&&>(x4)
|
||||
, static_cast<X3&&>(x3)
|
||||
, static_cast<X2&&>(x2)
|
||||
, static_cast<X1&&>(x1)
|
||||
), static_cast<Xn&&>(xn)...);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr reverse_apply_unrolled_impl reverse_apply_unrolled{};
|
||||
}} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VARIADIC_REVERSE_APPLY_UNROLLED_HPP
|
@ -0,0 +1,153 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::variadic::split_at`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VARIADIC_SPLIT_AT_HPP
|
||||
#define BOOST_HANA_DETAIL_VARIADIC_SPLIT_AT_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/functional/partial.hpp>
|
||||
#include <boost/hana/functional/reverse_partial.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail { namespace variadic {
|
||||
template <std::size_t n>
|
||||
struct split_at_t {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename X8, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, X8&& x8, Xs&& ...xs) const {
|
||||
return split_at_t<n - 8>{}(
|
||||
hana::partial(static_cast<F&&>(f),
|
||||
static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X3&&>(x3),
|
||||
static_cast<X4&&>(x4),
|
||||
static_cast<X5&&>(x5),
|
||||
static_cast<X6&&>(x6),
|
||||
static_cast<X7&&>(x7),
|
||||
static_cast<X8&&>(x8)
|
||||
),
|
||||
static_cast<Xs&&>(xs)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct split_at_t<0> {
|
||||
template <typename F, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, Xs&& ...xs) const {
|
||||
return static_cast<F&&>(f)()(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct split_at_t<1> {
|
||||
template <typename F, typename X1, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, Xs&& ...xs) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X1&&>(x1)
|
||||
)(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct split_at_t<2> {
|
||||
template <typename F, typename X1, typename X2, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, Xs&& ...xs) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2)
|
||||
)(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct split_at_t<3> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, Xs&& ...xs) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X3&&>(x3)
|
||||
)(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct split_at_t<4> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, Xs&& ...xs) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X3&&>(x3),
|
||||
static_cast<X4&&>(x4)
|
||||
)(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct split_at_t<5> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, Xs&& ...xs) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X3&&>(x3),
|
||||
static_cast<X4&&>(x4),
|
||||
static_cast<X5&&>(x5)
|
||||
)(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct split_at_t<6> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, Xs&& ...xs) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X3&&>(x3),
|
||||
static_cast<X4&&>(x4),
|
||||
static_cast<X5&&>(x5),
|
||||
static_cast<X6&&>(x6)
|
||||
)(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct split_at_t<7> {
|
||||
template <typename F, typename X1, typename X2, typename X3, typename X4, typename X5, typename X6, typename X7, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, X1&& x1, X2&& x2, X3&& x3, X4&& x4, X5&& x5, X6&& x6, X7&& x7, Xs&& ...xs) const {
|
||||
return static_cast<F&&>(f)(
|
||||
static_cast<X1&&>(x1),
|
||||
static_cast<X2&&>(x2),
|
||||
static_cast<X3&&>(x3),
|
||||
static_cast<X4&&>(x4),
|
||||
static_cast<X5&&>(x5),
|
||||
static_cast<X6&&>(x6),
|
||||
static_cast<X7&&>(x7)
|
||||
)(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
struct _makesplit_at_t {
|
||||
template <typename ...Xs>
|
||||
constexpr decltype(auto) operator()(Xs&& ...xs) const {
|
||||
return hana::reverse_partial(split_at_t<n>{},
|
||||
static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr _makesplit_at_t<n> split_at{};
|
||||
}} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VARIADIC_SPLIT_AT_HPP
|
@ -0,0 +1,51 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::variadic::take`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VARIADIC_TAKE_HPP
|
||||
#define BOOST_HANA_DETAIL_VARIADIC_TAKE_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/variadic/split_at.hpp>
|
||||
#include <boost/hana/functional/always.hpp>
|
||||
#include <boost/hana/functional/reverse_partial.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail { namespace variadic {
|
||||
struct take_impl2 {
|
||||
template <typename F, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(F&& f, Xs&& ...xs) const {
|
||||
return static_cast<F&&>(f)(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
struct take_impl1 {
|
||||
template <typename ...Xs>
|
||||
constexpr auto operator()(Xs&& ...xs) const {
|
||||
return hana::always(
|
||||
reverse_partial(take_impl2{},
|
||||
static_cast<Xs&&>(xs)...)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
struct take_t {
|
||||
template <typename ...Xs>
|
||||
constexpr decltype(auto) operator()(Xs&& ...xs) const {
|
||||
return variadic::split_at<n>(static_cast<Xs&&>(xs)...)(take_impl1{});
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr take_t<n> take{};
|
||||
}} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VARIADIC_TAKE_HPP
|
@ -0,0 +1,21 @@
|
||||
/*!
|
||||
@file
|
||||
Defines an equivalent to the proposed `std::void_t`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_VOID_T_HPP
|
||||
#define BOOST_HANA_DETAIL_VOID_T_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail {
|
||||
template <typename ...>
|
||||
using void_t = void;
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_VOID_T_HPP
|
@ -0,0 +1,33 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::detail::wrong`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_DETAIL_WRONG_HPP
|
||||
#define BOOST_HANA_DETAIL_WRONG_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace detail {
|
||||
//! @ingroup group-detail
|
||||
//! Equivalent to a type-dependent `std::false_type`.
|
||||
//!
|
||||
//! This is useful for making a static assertion that would otherwise
|
||||
//! always fire up dependent on some template parameters.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/detail/wrong.cpp
|
||||
template <typename ...>
|
||||
struct wrong : std::false_type { };
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DETAIL_WRONG_HPP
|
40
_deps/boost-src/libs/hana/include/boost/hana/difference.hpp
Normal file
40
_deps/boost-src/libs/hana/include/boost/hana/difference.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::difference`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_DIFFERENCE_HPP
|
||||
#define BOOST_HANA_DIFFERENCE_HPP
|
||||
|
||||
#include <boost/hana/fwd/difference.hpp>
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/erase_key.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename Ys>
|
||||
constexpr auto difference_t::operator()(Xs&& xs, Ys&& ys) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using Difference = BOOST_HANA_DISPATCH_IF(difference_impl<S>,
|
||||
true
|
||||
);
|
||||
|
||||
return Difference::apply(static_cast<Xs&&>(xs), static_cast<Ys&&>(ys));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename S, bool condition>
|
||||
struct difference_impl<S, when<condition>> : default_ {
|
||||
template <typename ...Args>
|
||||
static constexpr auto apply(Args&& ...) = delete;
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DIFFERENCE_HPP
|
107
_deps/boost-src/libs/hana/include/boost/hana/div.hpp
Normal file
107
_deps/boost-src/libs/hana/include/boost/hana/div.hpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::div`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_DIV_HPP
|
||||
#define BOOST_HANA_DIV_HPP
|
||||
|
||||
#include <boost/hana/fwd/div.hpp>
|
||||
|
||||
#include <boost/hana/concept/constant.hpp>
|
||||
#include <boost/hana/concept/euclidean_ring.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/to.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/detail/canonical_constant.hpp>
|
||||
#include <boost/hana/detail/has_common_embedding.hpp>
|
||||
#include <boost/hana/value.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename X, typename Y>
|
||||
constexpr decltype(auto) div_t::operator()(X&& x, Y&& y) const {
|
||||
using T = typename hana::tag_of<X>::type;
|
||||
using U = typename hana::tag_of<Y>::type;
|
||||
using Div = BOOST_HANA_DISPATCH_IF(decltype(div_impl<T, U>{}),
|
||||
hana::EuclideanRing<T>::value &&
|
||||
hana::EuclideanRing<U>::value &&
|
||||
!is_default<div_impl<T, U>>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::EuclideanRing<T>::value,
|
||||
"hana::div(x, y) requires 'x' to be an EuclideanRing");
|
||||
|
||||
static_assert(hana::EuclideanRing<U>::value,
|
||||
"hana::div(x, y) requires 'y' to be an EuclideanRing");
|
||||
|
||||
static_assert(!is_default<div_impl<T, U>>::value,
|
||||
"hana::div(x, y) requires 'x' and 'y' to be embeddable "
|
||||
"in a common EuclideanRing");
|
||||
#endif
|
||||
|
||||
return Div::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename T, typename U, bool condition>
|
||||
struct div_impl<T, U, when<condition>> : default_ {
|
||||
template <typename ...Args>
|
||||
static constexpr auto apply(Args&& ...) = delete;
|
||||
};
|
||||
|
||||
// Cross-type overload
|
||||
template <typename T, typename U>
|
||||
struct div_impl<T, U, when<
|
||||
detail::has_nontrivial_common_embedding<EuclideanRing, T, U>::value
|
||||
>> {
|
||||
using C = typename common<T, U>::type;
|
||||
template <typename X, typename Y>
|
||||
static constexpr decltype(auto) apply(X&& x, Y&& y) {
|
||||
return hana::div(hana::to<C>(static_cast<X&&>(x)),
|
||||
hana::to<C>(static_cast<Y&&>(y)));
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Model for integral data types
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct div_impl<T, T, when<std::is_integral<T>::value &&
|
||||
!std::is_same<T, bool>::value>> {
|
||||
template <typename X, typename Y>
|
||||
static constexpr decltype(auto) apply(X&& x, Y&& y)
|
||||
{ return static_cast<X&&>(x) / static_cast<Y&&>(y); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Model for Constants over an EuclideanRing
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
namespace detail {
|
||||
template <typename C, typename X, typename Y>
|
||||
struct constant_from_div {
|
||||
static constexpr auto value = hana::div(hana::value<X>(), hana::value<Y>());
|
||||
using hana_tag = detail::CanonicalConstant<typename C::value_type>;
|
||||
};
|
||||
}
|
||||
|
||||
template <typename C>
|
||||
struct div_impl<C, C, when<
|
||||
hana::Constant<C>::value &&
|
||||
EuclideanRing<typename C::value_type>::value
|
||||
>> {
|
||||
template <typename X, typename Y>
|
||||
static constexpr decltype(auto) apply(X const&, Y const&)
|
||||
{ return hana::to<C>(detail::constant_from_div<C, X, Y>{}); }
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DIV_HPP
|
75
_deps/boost-src/libs/hana/include/boost/hana/drop_back.hpp
Normal file
75
_deps/boost-src/libs/hana/include/boost/hana/drop_back.hpp
Normal file
@ -0,0 +1,75 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::drop_back`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_DROP_BACK_HPP
|
||||
#define BOOST_HANA_DROP_BACK_HPP
|
||||
|
||||
#include <boost/hana/fwd/drop_back.hpp>
|
||||
|
||||
#include <boost/hana/at.hpp>
|
||||
#include <boost/hana/concept/integral_constant.hpp>
|
||||
#include <boost/hana/concept/sequence.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/core/make.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
#include <boost/hana/length.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename N>
|
||||
constexpr auto drop_back_t::operator()(Xs&& xs, N const& n) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using DropBack = BOOST_HANA_DISPATCH_IF(drop_back_impl<S>,
|
||||
hana::Sequence<S>::value &&
|
||||
hana::IntegralConstant<N>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Sequence<S>::value,
|
||||
"hana::drop_back(xs, n) requires 'xs' to be a Sequence");
|
||||
|
||||
static_assert(hana::IntegralConstant<N>::value,
|
||||
"hana::drop_back(xs, n) requires 'n' to be an IntegralConstant");
|
||||
#endif
|
||||
|
||||
static_assert(N::value >= 0,
|
||||
"hana::drop_back(xs, n) requires 'n' to be non-negative");
|
||||
|
||||
return DropBack::apply(static_cast<Xs&&>(xs), n);
|
||||
}
|
||||
|
||||
template <typename Xs>
|
||||
constexpr auto drop_back_t::operator()(Xs&& xs) const {
|
||||
return (*this)(static_cast<Xs&&>(xs), hana::size_c<1>);
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename S, bool condition>
|
||||
struct drop_back_impl<S, when<condition>> : default_ {
|
||||
template <typename Xs, std::size_t ...n>
|
||||
static constexpr auto drop_back_helper(Xs&& xs, std::index_sequence<n...>) {
|
||||
return hana::make<S>(hana::at_c<n>(static_cast<Xs&&>(xs))...);
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr std::size_t len = decltype(hana::length(xs))::value;
|
||||
return drop_back_helper(static_cast<Xs&&>(xs),
|
||||
std::make_index_sequence<(n > len ? 0 : len - n)>{});
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DROP_BACK_HPP
|
57
_deps/boost-src/libs/hana/include/boost/hana/drop_front.hpp
Normal file
57
_deps/boost-src/libs/hana/include/boost/hana/drop_front.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::drop_front`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_DROP_FRONT_HPP
|
||||
#define BOOST_HANA_DROP_FRONT_HPP
|
||||
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
|
||||
#include <boost/hana/concept/integral_constant.hpp>
|
||||
#include <boost/hana/concept/iterable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/core/tag_of.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename N>
|
||||
constexpr auto drop_front_t::operator()(Xs&& xs, N const& n) const {
|
||||
using It = typename hana::tag_of<Xs>::type;
|
||||
using DropFront = BOOST_HANA_DISPATCH_IF(drop_front_impl<It>,
|
||||
hana::Iterable<It>::value &&
|
||||
hana::IntegralConstant<N>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Iterable<It>::value,
|
||||
"hana::drop_front(xs, n) requires 'xs' to be an Iterable");
|
||||
|
||||
static_assert(hana::IntegralConstant<N>::value,
|
||||
"hana::drop_front(xs, n) requires 'n' to be an IntegralConstant");
|
||||
#endif
|
||||
|
||||
return DropFront::apply(static_cast<Xs&&>(xs), n);
|
||||
}
|
||||
|
||||
template <typename Xs>
|
||||
constexpr auto drop_front_t::operator()(Xs&& xs) const {
|
||||
return (*this)(static_cast<Xs&&>(xs), hana::size_t<1>{});
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename It, bool condition>
|
||||
struct drop_front_impl<It, when<condition>> : default_ {
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs&&, N const&) = delete;
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DROP_FRONT_HPP
|
@ -0,0 +1,85 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::drop_front_exactly`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_DROP_FRONT_EXACTLY_HPP
|
||||
#define BOOST_HANA_DROP_FRONT_EXACTLY_HPP
|
||||
|
||||
#include <boost/hana/fwd/drop_front_exactly.hpp>
|
||||
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/concept/integral_constant.hpp>
|
||||
#include <boost/hana/concept/iterable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/drop_front.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
#include <boost/hana/is_empty.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename N>
|
||||
constexpr auto drop_front_exactly_t::operator()(Xs&& xs, N const& n) const {
|
||||
using It = typename hana::tag_of<Xs>::type;
|
||||
using DropFrontExactly = BOOST_HANA_DISPATCH_IF(drop_front_exactly_impl<It>,
|
||||
hana::Iterable<It>::value &&
|
||||
hana::IntegralConstant<N>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Iterable<It>::value,
|
||||
"hana::drop_front_exactly(xs, n) requires 'xs' to be an Iterable");
|
||||
|
||||
static_assert(hana::IntegralConstant<N>::value,
|
||||
"hana::drop_front_exactly(xs, n) requires 'n' to be an IntegralConstant");
|
||||
#endif
|
||||
|
||||
static_assert(N::value >= 0,
|
||||
"hana::drop_front_exactly(xs, n) requires 'n' to be non-negative");
|
||||
|
||||
return DropFrontExactly::apply(static_cast<Xs&&>(xs), n);
|
||||
}
|
||||
|
||||
template <typename Xs>
|
||||
constexpr auto drop_front_exactly_t::operator()(Xs&& xs) const {
|
||||
return (*this)(static_cast<Xs&&>(xs), hana::size_c<1>);
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
namespace detail {
|
||||
template <typename Xs, typename N>
|
||||
constexpr void check_dfe_overflow(Xs const& xs, N const&, hana::true_) {
|
||||
constexpr bool n_overflew_length = decltype(
|
||||
hana::is_empty(hana::drop_front(xs, hana::size_c<N::value - 1>))
|
||||
)::value;
|
||||
static_assert(!n_overflew_length,
|
||||
"hana::drop_front_exactly(xs, n) requires 'n' to be less than or "
|
||||
"equal to the number of elements in 'xs'");
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
constexpr void check_dfe_overflow(Xs const&, N const&, hana::false_) { }
|
||||
}
|
||||
|
||||
template <typename It, bool condition>
|
||||
struct drop_front_exactly_impl<It, when<condition>> : default_ {
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs&& xs, N const& n) {
|
||||
auto result = hana::drop_front(static_cast<Xs&&>(xs), n);
|
||||
constexpr bool check_for_overflow =
|
||||
decltype(hana::is_empty(result))::value && N::value != 0;
|
||||
|
||||
detail::check_dfe_overflow(xs, n, hana::bool_c<check_for_overflow>);
|
||||
|
||||
return result; // NRVO applied
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DROP_FRONT_EXACTLY_HPP
|
93
_deps/boost-src/libs/hana/include/boost/hana/drop_while.hpp
Normal file
93
_deps/boost-src/libs/hana/include/boost/hana/drop_while.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::drop_while`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_DROP_WHILE_HPP
|
||||
#define BOOST_HANA_DROP_WHILE_HPP
|
||||
|
||||
#include <boost/hana/fwd/drop_while.hpp>
|
||||
|
||||
#include <boost/hana/concept/foldable.hpp>
|
||||
#include <boost/hana/concept/iterable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/detail/first_unsatisfied_index.hpp>
|
||||
#include <boost/hana/drop_front.hpp>
|
||||
#include <boost/hana/eval_if.hpp>
|
||||
#include <boost/hana/front.hpp>
|
||||
#include <boost/hana/is_empty.hpp>
|
||||
#include <boost/hana/lazy.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename Pred>
|
||||
constexpr auto drop_while_t::operator()(Xs&& xs, Pred&& pred) const {
|
||||
using It = typename hana::tag_of<Xs>::type;
|
||||
using DropWhile = BOOST_HANA_DISPATCH_IF(drop_while_impl<It>,
|
||||
hana::Iterable<It>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Iterable<It>::value,
|
||||
"hana::drop_while(xs, pred) requires 'xs' to be an Iterable");
|
||||
#endif
|
||||
|
||||
return DropWhile::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
namespace iterable_detail {
|
||||
struct drop_while_helper {
|
||||
struct next {
|
||||
template <typename Xs, typename Pred>
|
||||
constexpr decltype(auto) operator()(Xs&& xs, Pred&& pred) const {
|
||||
return hana::drop_while(
|
||||
hana::drop_front(static_cast<Xs&&>(xs)),
|
||||
static_cast<Pred&&>(pred)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Xs, typename Pred>
|
||||
constexpr decltype(auto) operator()(Xs&& xs, Pred&& pred) const {
|
||||
return hana::eval_if(pred(hana::front(xs)),
|
||||
hana::make_lazy(next{})(xs, pred),
|
||||
hana::make_lazy(xs)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename It, bool condition>
|
||||
struct drop_while_impl<It, when<condition>> : default_ {
|
||||
template <typename Xs, typename Pred>
|
||||
static constexpr auto apply(Xs&& xs, Pred&& pred) {
|
||||
return hana::eval_if(hana::is_empty(xs),
|
||||
hana::make_lazy(xs),
|
||||
hana::make_lazy(iterable_detail::drop_while_helper{})(
|
||||
xs, static_cast<Pred&&>(pred))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct drop_while_impl<S, when<hana::Foldable<S>::value>> {
|
||||
template <typename Xs, typename Pred>
|
||||
static constexpr auto apply(Xs&& xs, Pred&&) {
|
||||
using FirstUnsatisfied = decltype(
|
||||
hana::unpack(static_cast<Xs&&>(xs),
|
||||
detail::first_unsatisfied_index<Pred&&>{})
|
||||
);
|
||||
return hana::drop_front(static_cast<Xs&&>(xs),
|
||||
FirstUnsatisfied{});
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DROP_WHILE_HPP
|
48
_deps/boost-src/libs/hana/include/boost/hana/duplicate.hpp
Normal file
48
_deps/boost-src/libs/hana/include/boost/hana/duplicate.hpp
Normal file
@ -0,0 +1,48 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::duplicate`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_DUPLICATE_HPP
|
||||
#define BOOST_HANA_DUPLICATE_HPP
|
||||
|
||||
#include <boost/hana/fwd/duplicate.hpp>
|
||||
|
||||
#include <boost/hana/concept/comonad.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/extend.hpp>
|
||||
#include <boost/hana/functional/id.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename W_>
|
||||
constexpr decltype(auto) duplicate_t::operator()(W_&& w) const {
|
||||
using W = typename hana::tag_of<W_>::type;
|
||||
using Duplicate = BOOST_HANA_DISPATCH_IF(duplicate_impl<W>,
|
||||
hana::Comonad<W>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Comonad<W>::value,
|
||||
"hana::duplicate(w) requires 'w' to be a Comonad");
|
||||
#endif
|
||||
|
||||
return Duplicate::apply(static_cast<W_&&>(w));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename W, bool condition>
|
||||
struct duplicate_impl<W, when<condition>> : default_ {
|
||||
template <typename X>
|
||||
static constexpr decltype(auto) apply(X&& x)
|
||||
{ return hana::extend(static_cast<X&&>(x), hana::id); }
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_DUPLICATE_HPP
|
53
_deps/boost-src/libs/hana/include/boost/hana/empty.hpp
Normal file
53
_deps/boost-src/libs/hana/include/boost/hana/empty.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::empty`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_EMPTY_HPP
|
||||
#define BOOST_HANA_EMPTY_HPP
|
||||
|
||||
#include <boost/hana/fwd/empty.hpp>
|
||||
|
||||
#include <boost/hana/concept/monad_plus.hpp>
|
||||
#include <boost/hana/concept/sequence.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/core/make.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename M>
|
||||
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
|
||||
|
||||
using Empty = BOOST_HANA_DISPATCH_IF(empty_impl<M>,
|
||||
hana::MonadPlus<M>::value
|
||||
);
|
||||
|
||||
return Empty::apply();
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename M, bool condition>
|
||||
struct empty_impl<M, when<condition>> : default_ {
|
||||
template <typename ...Args>
|
||||
static constexpr auto apply(Args&& ...) = delete;
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct empty_impl<S, when<Sequence<S>::value>> {
|
||||
static constexpr auto apply() {
|
||||
return hana::make<S>();
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EMPTY_HPP
|
206
_deps/boost-src/libs/hana/include/boost/hana/equal.hpp
Normal file
206
_deps/boost-src/libs/hana/include/boost/hana/equal.hpp
Normal file
@ -0,0 +1,206 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::equal`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_EQUAL_HPP
|
||||
#define BOOST_HANA_EQUAL_HPP
|
||||
|
||||
#include <boost/hana/fwd/equal.hpp>
|
||||
|
||||
#include <boost/hana/accessors.hpp>
|
||||
#include <boost/hana/all_of.hpp>
|
||||
#include <boost/hana/and.hpp>
|
||||
#include <boost/hana/at.hpp>
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/concept/comparable.hpp>
|
||||
#include <boost/hana/concept/constant.hpp>
|
||||
#include <boost/hana/concept/product.hpp>
|
||||
#include <boost/hana/concept/sequence.hpp>
|
||||
#include <boost/hana/concept/struct.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/common.hpp>
|
||||
#include <boost/hana/core/to.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/core/tag_of.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/detail/concepts.hpp>
|
||||
#include <boost/hana/detail/has_common_embedding.hpp>
|
||||
#include <boost/hana/detail/nested_to.hpp> // required by fwd decl
|
||||
#include <boost/hana/first.hpp>
|
||||
#include <boost/hana/if.hpp>
|
||||
#include <boost/hana/length.hpp>
|
||||
#include <boost/hana/second.hpp>
|
||||
#include <boost/hana/value.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename X, typename Y>
|
||||
constexpr auto equal_t::operator()(X&& x, Y&& y) const {
|
||||
using T = typename hana::tag_of<X>::type;
|
||||
using U = typename hana::tag_of<Y>::type;
|
||||
using Equal = equal_impl<T, U>;
|
||||
return Equal::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename T, typename U, bool condition>
|
||||
struct equal_impl<T, U, when<condition>> : default_ {
|
||||
template <typename X, typename Y>
|
||||
static constexpr auto apply(X const&, Y const&) {
|
||||
// Delay the static_assert by ensuring T_ is dependent.
|
||||
using T_ = typename hana::tag_of<X>::type;
|
||||
static_assert(!hana::is_convertible<T_, U>::value &&
|
||||
!hana::is_convertible<U, T_>::value,
|
||||
"No default implementation of hana::equal is provided for related "
|
||||
"types that can't be safely embedded into a common type, because "
|
||||
"those are most likely programming errors. If this is really what "
|
||||
"you want, you can manually convert both objects to a common "
|
||||
"Comparable type before performing the comparison. If you think "
|
||||
"you have made your types Comparable but you see this, perhaps you "
|
||||
"forgot to define some of the necessary methods for an automatic "
|
||||
"model of Comparable to kick in. A possible culprit is defining "
|
||||
"'operator==' but not 'operator!='.");
|
||||
|
||||
return hana::false_c;
|
||||
}
|
||||
};
|
||||
|
||||
// Cross-type overload
|
||||
template <typename T, typename U>
|
||||
struct equal_impl<T, U, when<
|
||||
detail::has_nontrivial_common_embedding<Comparable, T, U>::value &&
|
||||
!detail::EqualityComparable<T, U>::value
|
||||
>> {
|
||||
using C = typename hana::common<T, U>::type;
|
||||
template <typename X, typename Y>
|
||||
static constexpr auto apply(X&& x, Y&& y) {
|
||||
return hana::equal(hana::to<C>(static_cast<X&&>(x)),
|
||||
hana::to<C>(static_cast<Y&&>(y)));
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Model for EqualityComparable data types
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename U>
|
||||
struct equal_impl<T, U, when<detail::EqualityComparable<T, U>::value>> {
|
||||
template <typename X, typename Y>
|
||||
static constexpr auto apply(X&& x, Y&& y)
|
||||
{ return static_cast<X&&>(x) == static_cast<Y&&>(y); }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Model for Constants wrapping a Comparable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename C>
|
||||
struct equal_impl<C, C, when<
|
||||
hana::Constant<C>::value &&
|
||||
Comparable<typename C::value_type>::value
|
||||
>> {
|
||||
template <typename X, typename Y>
|
||||
static constexpr auto apply(X const&, Y const&) {
|
||||
constexpr auto eq = hana::equal(hana::value<X>(), hana::value<Y>());
|
||||
constexpr bool truth_value = hana::if_(eq, true, false);
|
||||
return hana::bool_<truth_value>{};
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Comparable for Products
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename T, typename U>
|
||||
struct equal_impl<T, U, when<hana::Product<T>::value && hana::Product<U>::value>> {
|
||||
template <typename X, typename Y>
|
||||
static constexpr auto apply(X const& x, Y const& y) {
|
||||
return hana::and_(
|
||||
hana::equal(hana::first(x), hana::first(y)),
|
||||
hana::equal(hana::second(x), hana::second(y))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Comparable for Sequences
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
namespace detail {
|
||||
template <typename Xs, typename Ys, std::size_t Length>
|
||||
struct compare_finite_sequences {
|
||||
Xs const& xs;
|
||||
Ys const& ys;
|
||||
|
||||
template <std::size_t i>
|
||||
constexpr auto apply(hana::false_, hana::true_) const {
|
||||
return compare_finite_sequences::apply<i+1>(
|
||||
hana::bool_<i+1 == Length>{},
|
||||
hana::if_(hana::equal(hana::at_c<i>(xs), hana::at_c<i>(ys)),
|
||||
hana::true_c, hana::false_c)
|
||||
);
|
||||
}
|
||||
|
||||
template <std::size_t i>
|
||||
constexpr auto apply(hana::false_, hana::false_) const
|
||||
{ return hana::false_c; }
|
||||
|
||||
template <std::size_t i, typename Result>
|
||||
constexpr auto apply(hana::true_, Result r) const
|
||||
{ return r; }
|
||||
|
||||
template <std::size_t i>
|
||||
constexpr bool apply(hana::false_, bool b) const {
|
||||
return b && compare_finite_sequences::apply<i+1>(
|
||||
hana::bool_<i+1 == Length>{},
|
||||
hana::if_(hana::equal(hana::at_c<i>(xs), hana::at_c<i>(ys)),
|
||||
hana::true_c, hana::false_c)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
struct equal_impl<T, U, when<Sequence<T>::value && hana::Sequence<U>::value>> {
|
||||
template <typename Xs, typename Ys>
|
||||
static constexpr auto apply(Xs const& xs, Ys const& ys) {
|
||||
constexpr std::size_t xs_size = decltype(hana::length(xs))::value;
|
||||
constexpr std::size_t ys_size = decltype(hana::length(ys))::value;
|
||||
detail::compare_finite_sequences<Xs, Ys, xs_size> comp{xs, ys};
|
||||
return comp.template apply<0>(hana::bool_<xs_size == 0>{},
|
||||
hana::bool_<xs_size == ys_size>{});
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename X, typename Y>
|
||||
struct compare_struct_members {
|
||||
X const& x;
|
||||
Y const& y;
|
||||
|
||||
template <typename Member>
|
||||
constexpr auto operator()(Member&& member) const {
|
||||
auto accessor = hana::second(static_cast<Member&&>(member));
|
||||
return hana::equal(accessor(x), accessor(y));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
struct equal_impl<S, S, when<
|
||||
hana::Struct<S>::value &&
|
||||
!detail::EqualityComparable<S, S>::value
|
||||
>> {
|
||||
template <typename X, typename Y>
|
||||
static constexpr auto apply(X const& x, Y const& y) {
|
||||
return hana::all_of(hana::accessors<S>(),
|
||||
detail::compare_struct_members<X, Y>{x, y});
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EQUAL_HPP
|
37
_deps/boost-src/libs/hana/include/boost/hana/erase_key.hpp
Normal file
37
_deps/boost-src/libs/hana/include/boost/hana/erase_key.hpp
Normal file
@ -0,0 +1,37 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::erase_key`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ERASE_KEY_HPP
|
||||
#define BOOST_HANA_ERASE_KEY_HPP
|
||||
|
||||
#include <boost/hana/fwd/erase_key.hpp>
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Set, typename ...Args>
|
||||
constexpr decltype(auto) erase_key_t::operator()(Set&& set, Args&& ...args) const {
|
||||
return erase_key_impl<typename hana::tag_of<Set>::type>::apply(
|
||||
static_cast<Set&&>(set),
|
||||
static_cast<Args&&>(args)...
|
||||
);
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename T, bool condition>
|
||||
struct erase_key_impl<T, when<condition>> : default_ {
|
||||
template <typename ...Args>
|
||||
static constexpr auto apply(Args&& ...) = delete;
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_ERASE_KEY_HPP
|
57
_deps/boost-src/libs/hana/include/boost/hana/eval.hpp
Normal file
57
_deps/boost-src/libs/hana/include/boost/hana/eval.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::eval`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_EVAL_HPP
|
||||
#define BOOST_HANA_EVAL_HPP
|
||||
|
||||
#include <boost/hana/fwd/eval.hpp>
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/detail/wrong.hpp>
|
||||
#include <boost/hana/functional/id.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Expr>
|
||||
constexpr decltype(auto) eval_t::operator()(Expr&& expr) const {
|
||||
return eval_impl<typename hana::tag_of<Expr>::type>::apply(
|
||||
static_cast<Expr&&>(expr)
|
||||
);
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename T, bool condition>
|
||||
struct eval_impl<T, when<condition>> : default_ {
|
||||
template <typename Expr>
|
||||
static constexpr auto eval_helper(Expr&& expr, int)
|
||||
-> decltype(static_cast<Expr&&>(expr)())
|
||||
{ return static_cast<Expr&&>(expr)(); }
|
||||
|
||||
template <typename Expr>
|
||||
static constexpr auto eval_helper(Expr&& expr, long)
|
||||
-> decltype(static_cast<Expr&&>(expr)(hana::id))
|
||||
{ return static_cast<Expr&&>(expr)(hana::id); }
|
||||
|
||||
template <typename Expr>
|
||||
static constexpr auto eval_helper(Expr&&, ...) {
|
||||
static_assert(detail::wrong<Expr>{},
|
||||
"hana::eval(expr) requires the expression to be a hana::lazy, "
|
||||
"a nullary Callable or a unary Callable that may be "
|
||||
"called with hana::id");
|
||||
}
|
||||
|
||||
template <typename Expr>
|
||||
static constexpr decltype(auto) apply(Expr&& expr)
|
||||
{ return eval_helper(static_cast<Expr&&>(expr), int{}); }
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EVAL_HPP
|
93
_deps/boost-src/libs/hana/include/boost/hana/eval_if.hpp
Normal file
93
_deps/boost-src/libs/hana/include/boost/hana/eval_if.hpp
Normal file
@ -0,0 +1,93 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::eval_if`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_EVAL_IF_HPP
|
||||
#define BOOST_HANA_EVAL_IF_HPP
|
||||
|
||||
#include <boost/hana/fwd/eval_if.hpp>
|
||||
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/concept/constant.hpp>
|
||||
#include <boost/hana/concept/logical.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/eval.hpp>
|
||||
#include <boost/hana/if.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Cond, typename Then, typename Else>
|
||||
constexpr decltype(auto) eval_if_t::operator()(Cond&& cond, Then&& then_, Else&& else_) const {
|
||||
using Bool = typename hana::tag_of<Cond>::type;
|
||||
using EvalIf = BOOST_HANA_DISPATCH_IF(eval_if_impl<Bool>,
|
||||
hana::Logical<Bool>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Logical<Bool>::value,
|
||||
"hana::eval_if(cond, then, else) requires 'cond' to be a Logical");
|
||||
#endif
|
||||
|
||||
return EvalIf::apply(static_cast<Cond&&>(cond),
|
||||
static_cast<Then&&>(then_),
|
||||
static_cast<Else&&>(else_));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename L, bool condition>
|
||||
struct eval_if_impl<L, when<condition>> : default_ {
|
||||
template <typename ...Args>
|
||||
static constexpr auto apply(Args&& ...) = delete;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Model for arithmetic data types
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename L>
|
||||
struct eval_if_impl<L, when<std::is_arithmetic<L>::value>> {
|
||||
template <typename Cond, typename T, typename E>
|
||||
static constexpr auto apply(Cond const& cond, T&& t, E&& e) {
|
||||
return cond ? hana::eval(static_cast<T&&>(t))
|
||||
: hana::eval(static_cast<E&&>(e));
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Model for Constants over a Logical
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename C>
|
||||
struct eval_if_impl<C, when<
|
||||
hana::Constant<C>::value &&
|
||||
Logical<typename C::value_type>::value
|
||||
>> {
|
||||
template <typename Then, typename Else>
|
||||
static constexpr decltype(auto)
|
||||
eval_if_helper(hana::true_, Then&& t, Else&&)
|
||||
{ return hana::eval(static_cast<Then&&>(t)); }
|
||||
|
||||
template <typename Then, typename Else>
|
||||
static constexpr decltype(auto)
|
||||
eval_if_helper(hana::false_, Then&&, Else&& e)
|
||||
{ return hana::eval(static_cast<Else&&>(e)); }
|
||||
|
||||
template <typename Cond, typename Then, typename Else>
|
||||
static constexpr decltype(auto) apply(Cond const&, Then&& t, Else&& e) {
|
||||
constexpr auto cond = hana::value<Cond>();
|
||||
constexpr bool truth_value = hana::if_(cond, true, false);
|
||||
return eval_if_helper(hana::bool_<truth_value>{},
|
||||
static_cast<Then&&>(t),
|
||||
static_cast<Else&&>(e));
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EVAL_IF_HPP
|
@ -0,0 +1,257 @@
|
||||
/*
|
||||
@file
|
||||
Defines `boost::hana::experimental::print`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXPERIMENTAL_PRINTABLE_HPP
|
||||
#define BOOST_HANA_EXPERIMENTAL_PRINTABLE_HPP
|
||||
|
||||
#include <boost/hana/concept/constant.hpp>
|
||||
#include <boost/hana/concept/product.hpp>
|
||||
#include <boost/hana/concept/sequence.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/to.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/first.hpp>
|
||||
#include <boost/hana/for_each.hpp>
|
||||
#include <boost/hana/intersperse.hpp>
|
||||
#include <boost/hana/second.hpp>
|
||||
#include <boost/hana/transform.hpp>
|
||||
#include <boost/hana/tuple.hpp>
|
||||
|
||||
// models for different containers
|
||||
#include <boost/hana/fwd/map.hpp>
|
||||
#include <boost/hana/fwd/optional.hpp>
|
||||
#include <boost/hana/fwd/set.hpp>
|
||||
#include <boost/hana/fwd/string.hpp>
|
||||
#include <boost/hana/fwd/type.hpp>
|
||||
|
||||
#include <boost/core/demangle.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <regex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <typeinfo>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace experimental {
|
||||
template <typename T>
|
||||
struct Printable;
|
||||
|
||||
//! @cond
|
||||
template <typename T, typename = void>
|
||||
struct print_impl : print_impl<T, hana::when<true>> { };
|
||||
|
||||
template <typename T, bool condition>
|
||||
struct print_impl<T, hana::when<condition>> : hana::default_ {
|
||||
template <typename ...Args>
|
||||
static constexpr auto apply(Args&& ...) = delete;
|
||||
};
|
||||
//! @endcond
|
||||
|
||||
//! @ingroup group-experimental
|
||||
//! Returns a string representation of the given object.
|
||||
//!
|
||||
//! This function is defined for most containers provided by Hana, and
|
||||
//! also for objects that define an `operator<<` that can be used with
|
||||
//! a `std::basic_ostream`. It can recursively print containers within
|
||||
//! containers, but do not expect any kind of proper indentation.
|
||||
//!
|
||||
//! This function requires (the rest of) Boost to be available on the
|
||||
//! system. It also requires RTTI to be enabled.
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
auto print = [](auto const& x) -> std::string {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
struct print_t {
|
||||
template <typename T>
|
||||
std::string operator()(T const& t) const {
|
||||
using Tag = typename hana::tag_of<T>::type;
|
||||
using Print = BOOST_HANA_DISPATCH_IF(print_impl<Tag>,
|
||||
hana::experimental::Printable<Tag>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::experimental::Printable<Tag>::value,
|
||||
"hana::experimental::print(t) requires 't' to be Printable");
|
||||
#endif
|
||||
|
||||
return Print::apply(t);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr print_t print{};
|
||||
#endif
|
||||
|
||||
// Define the `Printable` concept
|
||||
template <typename T>
|
||||
struct Printable {
|
||||
using Tag = typename hana::tag_of<T>::type;
|
||||
static constexpr bool value = !hana::is_default<print_impl<Tag>>::value;
|
||||
};
|
||||
|
||||
namespace print_detail {
|
||||
inline std::string strip_type_junk(std::string const& str) {
|
||||
return std::regex_replace(str, std::regex("(?:struct )?([a-z_]+::)*([a-z_]*)_t<((?:struct )?[a-z:<>_]*)>"), "$2<$3>");
|
||||
}
|
||||
}
|
||||
|
||||
// model for Sequences
|
||||
template <typename S>
|
||||
struct print_impl<S, hana::when<hana::Sequence<S>::value>> {
|
||||
template <typename Xs>
|
||||
static std::string apply(Xs const& xs) {
|
||||
std::string result = "(";
|
||||
auto comma_separated = hana::intersperse(xs, ", ");
|
||||
hana::for_each(comma_separated, [&result](auto const& x) {
|
||||
result += hana::experimental::print(x);
|
||||
});
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// model for OutputStreamable types
|
||||
//! @cond
|
||||
template <typename S>
|
||||
struct print_impl<S, hana::when_valid<decltype(
|
||||
std::declval<std::ostringstream&>() << std::declval<S const&>()
|
||||
)>> {
|
||||
template <typename T>
|
||||
static std::string apply(T const& t) {
|
||||
std::ostringstream os;
|
||||
os << t;
|
||||
return os.str();
|
||||
}
|
||||
};
|
||||
//! @endcond
|
||||
|
||||
// model for hana::optional
|
||||
template <>
|
||||
struct print_impl<hana::optional_tag> {
|
||||
template <typename O>
|
||||
static std::string apply(O const& optional) {
|
||||
return hana::maybe("nothing",
|
||||
[](auto const& x) {
|
||||
return "just(" + hana::experimental::print(x) + ")";
|
||||
}, optional);
|
||||
}
|
||||
};
|
||||
|
||||
// model for hana::maps
|
||||
template <>
|
||||
struct print_impl<hana::map_tag> {
|
||||
template <typename M>
|
||||
static std::string apply(M const& map) {
|
||||
std::string result = "{";
|
||||
auto pairs = hana::transform(hana::to_tuple(map),
|
||||
[](auto const& pair) {
|
||||
return hana::experimental::print(hana::first(pair))
|
||||
+ " => "
|
||||
+ hana::experimental::print(hana::second(pair));
|
||||
});
|
||||
auto comma_separated = hana::intersperse(pairs, ", ");
|
||||
hana::for_each(comma_separated, [&result](auto const& element) {
|
||||
result += element;
|
||||
});
|
||||
result += "}";
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// model for hana::metafunctions
|
||||
template <template <typename ...> class F>
|
||||
struct print_impl<hana::metafunction_t<F>> {
|
||||
template <typename T>
|
||||
static std::string apply(T const&) {
|
||||
return print_detail::strip_type_junk(boost::core::demangle(typeid(T).name()));
|
||||
}
|
||||
};
|
||||
|
||||
// model for hana::metafunction_classes
|
||||
template <typename F>
|
||||
struct print_impl<hana::metafunction_class_t<F>> {
|
||||
template <typename T>
|
||||
static std::string apply(T const&) {
|
||||
return print_detail::strip_type_junk(boost::core::demangle(typeid(T).name()));
|
||||
}
|
||||
};
|
||||
|
||||
// model for Constants holding a `Printable`
|
||||
template <typename C>
|
||||
struct print_impl<C, hana::when<
|
||||
hana::Constant<C>::value &&
|
||||
Printable<typename C::value_type>::value
|
||||
>> {
|
||||
template <typename T>
|
||||
static std::string apply(T const&) {
|
||||
constexpr auto value = hana::value<T>();
|
||||
return hana::experimental::print(value);
|
||||
}
|
||||
};
|
||||
|
||||
// model for Products
|
||||
template <typename P>
|
||||
struct print_impl<P, hana::when<hana::Product<P>::value>> {
|
||||
template <typename T>
|
||||
static std::string apply(T const& t) {
|
||||
return '(' + hana::experimental::print(hana::first(t))
|
||||
+ ", "
|
||||
+ hana::experimental::print(hana::second(t)) + ')';
|
||||
}
|
||||
};
|
||||
|
||||
// model for hana::strings
|
||||
template <>
|
||||
struct print_impl<hana::string_tag> {
|
||||
template <typename S>
|
||||
static std::string apply(S const& s) {
|
||||
return '"' + std::string{hana::to<char const*>(s)} + '"';
|
||||
}
|
||||
};
|
||||
|
||||
// model for hana::sets
|
||||
template <>
|
||||
struct print_impl<hana::set_tag> {
|
||||
template <typename S>
|
||||
static std::string apply(S const& set) {
|
||||
std::string result = "{";
|
||||
auto as_tuple = hana::transform(hana::to_tuple(set),
|
||||
hana::experimental::print);
|
||||
auto comma_separated = hana::intersperse(as_tuple, ", ");
|
||||
hana::for_each(comma_separated, [&result](auto const& element) {
|
||||
result += element;
|
||||
});
|
||||
result += "}";
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// model for hana::templates
|
||||
template <template <typename ...> class F>
|
||||
struct print_impl<template_t<F>> {
|
||||
template <typename T>
|
||||
static std::string apply(T const&) {
|
||||
return print_detail::strip_type_junk(boost::core::demangle(typeid(T).name()));
|
||||
}
|
||||
};
|
||||
|
||||
// model for hana::types
|
||||
template <>
|
||||
struct print_impl<hana::type_tag> {
|
||||
template <typename T>
|
||||
static std::string apply(T const&) {
|
||||
using Type = typename T::type;
|
||||
return "type<" + boost::core::demangle(typeid(Type).name()) + '>';
|
||||
}
|
||||
};
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXPERIMENTAL_PRINTABLE_HPP
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
@file
|
||||
Defines `boost::hana::experimental::type_name`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXPERIMENTAL_TYPE_NAME_HPP
|
||||
#define BOOST_HANA_EXPERIMENTAL_TYPE_NAME_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/string.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana { namespace experimental {
|
||||
namespace detail {
|
||||
struct cstring {
|
||||
char const* ptr;
|
||||
std::size_t length;
|
||||
};
|
||||
|
||||
// Note: We substract the null terminator from the string sizes below.
|
||||
template <typename T>
|
||||
constexpr cstring type_name_impl2() {
|
||||
|
||||
#if defined(__clang__)
|
||||
constexpr char const* pretty_function = __PRETTY_FUNCTION__;
|
||||
constexpr std::size_t total_size = sizeof(__PRETTY_FUNCTION__) - 1;
|
||||
constexpr std::size_t prefix_size = sizeof("boost::hana::experimental::detail::cstring boost::hana::experimental::detail::type_name_impl2() [T = ") - 1;
|
||||
constexpr std::size_t suffix_size = sizeof("]") - 1;
|
||||
#else
|
||||
#error "No support for this compiler."
|
||||
#endif
|
||||
|
||||
return {pretty_function + prefix_size, total_size - prefix_size - suffix_size};
|
||||
}
|
||||
|
||||
template <typename T, std::size_t ...i>
|
||||
auto type_name_impl1(std::index_sequence<i...>) {
|
||||
constexpr auto name = detail::type_name_impl2<T>();
|
||||
return hana::string<*(name.ptr + i)...>{};
|
||||
}
|
||||
} // end namespace detail
|
||||
|
||||
//! @ingroup group-experimental
|
||||
//! Returns a `hana::string` representing the name of the given type, at
|
||||
//! compile-time.
|
||||
//!
|
||||
//! This only works on Clang (and apparently MSVC, but Hana does not work
|
||||
//! there as of writing this). Original idea taken from
|
||||
//! https://github.com/Manu343726/ctti.
|
||||
template <typename T>
|
||||
auto type_name() {
|
||||
constexpr auto name = detail::type_name_impl2<T>();
|
||||
return detail::type_name_impl1<T>(std::make_index_sequence<name.length>{});
|
||||
}
|
||||
} }} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXPERIMENTAL_TYPE_NAME_HPP
|
@ -0,0 +1,158 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::experimental::types`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXPERIMENTAL_TYPES_HPP
|
||||
#define BOOST_HANA_EXPERIMENTAL_TYPES_HPP
|
||||
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/concept/metafunction.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/any_of.hpp>
|
||||
#include <boost/hana/detail/type_at.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/contains.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/equal.hpp>
|
||||
#include <boost/hana/fwd/is_empty.hpp>
|
||||
#include <boost/hana/fwd/transform.hpp>
|
||||
#include <boost/hana/fwd/unpack.hpp>
|
||||
#include <boost/hana/type.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace experimental {
|
||||
//! @ingroup group-experimental
|
||||
//! Container optimized for holding types.
|
||||
//!
|
||||
//! It is often useful to manipulate a sequence that contains types
|
||||
//! only, without any associated runtime value. This container allows
|
||||
//! storing and manipulating pure types in a much more compile-time
|
||||
//! efficient manner than using `hana::tuple`, which must assume that
|
||||
//! its contents might have runtime values.
|
||||
template <typename ...T>
|
||||
struct types;
|
||||
|
||||
struct types_tag;
|
||||
|
||||
template <typename ...T>
|
||||
struct types { };
|
||||
} // end namespace experimental
|
||||
|
||||
template <typename ...T>
|
||||
struct tag_of<experimental::types<T...>> {
|
||||
using type = experimental::types_tag;
|
||||
};
|
||||
|
||||
// Foldable
|
||||
template <>
|
||||
struct unpack_impl<hana::experimental::types_tag> {
|
||||
template <typename ...T, typename F, typename = typename std::enable_if<
|
||||
!hana::Metafunction<F>::value
|
||||
>::type>
|
||||
static constexpr decltype(auto) apply(hana::experimental::types<T...> const&, F&& f) {
|
||||
return static_cast<F&&>(f)(hana::type<T>{}...);
|
||||
}
|
||||
|
||||
template <typename ...T, typename F, typename = typename std::enable_if<
|
||||
hana::Metafunction<F>::value
|
||||
>::type>
|
||||
static constexpr hana::type<typename F::template apply<T...>::type>
|
||||
apply(hana::experimental::types<T...> const&, F const&) { return {}; }
|
||||
};
|
||||
|
||||
// Functor
|
||||
template <>
|
||||
struct transform_impl<hana::experimental::types_tag> {
|
||||
template <typename ...T, typename F, typename = typename std::enable_if<
|
||||
!hana::Metafunction<F>::value
|
||||
>::type>
|
||||
static constexpr auto apply(hana::experimental::types<T...> const&, F&& f)
|
||||
-> hana::experimental::types<typename decltype(+f(hana::type<T>{}))::type...>
|
||||
{ return {}; }
|
||||
|
||||
template <typename ...T, typename F, typename = typename std::enable_if<
|
||||
hana::Metafunction<F>::value
|
||||
>::type>
|
||||
static constexpr hana::experimental::types<typename F::template apply<T>::type...>
|
||||
apply(hana::experimental::types<T...> const&, F const&) { return {}; }
|
||||
};
|
||||
|
||||
// Iterable
|
||||
template <>
|
||||
struct at_impl<hana::experimental::types_tag> {
|
||||
template <typename ...T, typename N>
|
||||
static constexpr auto
|
||||
apply(hana::experimental::types<T...> const&, N const&) {
|
||||
using Nth = typename detail::type_at<N::value, T...>::type;
|
||||
return hana::type<Nth>{};
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_empty_impl<hana::experimental::types_tag> {
|
||||
template <typename ...T>
|
||||
static constexpr hana::bool_<sizeof...(T) == 0>
|
||||
apply(hana::experimental::types<T...> const&)
|
||||
{ return {}; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct drop_front_impl<hana::experimental::types_tag> {
|
||||
template <std::size_t n, typename ...T, std::size_t ...i>
|
||||
static hana::experimental::types<typename detail::type_at<i + n, T...>::type...>
|
||||
helper(std::index_sequence<i...>);
|
||||
|
||||
template <typename ...T, typename N>
|
||||
static constexpr auto
|
||||
apply(hana::experimental::types<T...> const&, N const&) {
|
||||
constexpr std::size_t n = N::value > sizeof...(T) ? sizeof...(T) : N::value;
|
||||
using Indices = std::make_index_sequence<sizeof...(T) - n>;
|
||||
return decltype(helper<n, T...>(Indices{})){};
|
||||
}
|
||||
};
|
||||
|
||||
// Searchable
|
||||
template <>
|
||||
struct contains_impl<hana::experimental::types_tag> {
|
||||
template <typename U>
|
||||
struct is_same_as {
|
||||
template <typename T>
|
||||
struct apply {
|
||||
static constexpr bool value = std::is_same<U, T>::value;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename ...T, typename U>
|
||||
static constexpr auto apply(hana::experimental::types<T...> const&, U const&)
|
||||
-> hana::bool_<
|
||||
detail::any_of<is_same_as<typename U::type>::template apply, T...>::value
|
||||
>
|
||||
{ return {}; }
|
||||
|
||||
static constexpr hana::false_ apply(...) { return {}; }
|
||||
};
|
||||
|
||||
// Comparable
|
||||
template <>
|
||||
struct equal_impl<hana::experimental::types_tag, hana::experimental::types_tag> {
|
||||
template <typename Types>
|
||||
static constexpr hana::true_ apply(Types const&, Types const&)
|
||||
{ return {}; }
|
||||
|
||||
template <typename Ts, typename Us>
|
||||
static constexpr hana::false_ apply(Ts const&, Us const&)
|
||||
{ return {}; }
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXPERIMENTAL_TYPES_HPP
|
@ -0,0 +1,515 @@
|
||||
/*
|
||||
@file
|
||||
Defines experimental views.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXPERIMENTAL_VIEW_HPP
|
||||
#define BOOST_HANA_EXPERIMENTAL_VIEW_HPP
|
||||
|
||||
#include <boost/hana/and.hpp>
|
||||
#include <boost/hana/at.hpp>
|
||||
#include <boost/hana/bool.hpp>
|
||||
#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>
|
||||
#include <boost/hana/fwd/empty.hpp>
|
||||
#include <boost/hana/fwd/equal.hpp>
|
||||
#include <boost/hana/fwd/flatten.hpp>
|
||||
#include <boost/hana/fwd/is_empty.hpp>
|
||||
#include <boost/hana/fwd/less.hpp>
|
||||
#include <boost/hana/fwd/lift.hpp>
|
||||
#include <boost/hana/fwd/transform.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
#include <boost/hana/length.hpp>
|
||||
#include <boost/hana/lexicographical_compare.hpp>
|
||||
#include <boost/hana/range.hpp>
|
||||
#include <boost/hana/tuple.hpp>
|
||||
#include <boost/hana/unpack.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
// Pros of views
|
||||
// - No temporary container created between algorithms
|
||||
// - Lazy, so only the minimum is required
|
||||
//
|
||||
// Cons of views
|
||||
// - Reference semantics mean possibility for dangling references
|
||||
// - Lose the ability to move from temporary containers
|
||||
// - When fetching the members of a view multiple times, no caching is done.
|
||||
// So for example, `t = transform(xs, f); at_c<0>(t); at_c<0>(t)` will
|
||||
// compute `f(at_c<0>(xs))` twice.
|
||||
// - push_back creates a joint_view and a single_view. The single_view holds
|
||||
// the value as a member. When doing multiple push_backs, we end up with a
|
||||
// joint_view<xxx, joint_view<single_view<T>, joint_view<single_view<T>, ....>>>
|
||||
// which contains a reference to `xxx` and all the `T`s by value. Such a
|
||||
// "view" is not cheap to copy, which is inconsistent with the usual
|
||||
// expectations about views.
|
||||
|
||||
namespace boost { namespace hana {
|
||||
|
||||
namespace experimental {
|
||||
struct view_tag;
|
||||
|
||||
namespace detail {
|
||||
template <typename Sequence>
|
||||
struct is_view {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
|
||||
template <typename Sequence>
|
||||
using view_storage = typename std::conditional<
|
||||
detail::is_view<Sequence>::value, Sequence, Sequence&
|
||||
>::type;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// sliced_view
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename Sequence, std::size_t ...indices>
|
||||
struct sliced_view_t {
|
||||
detail::view_storage<Sequence> sequence_;
|
||||
using hana_tag = view_tag;
|
||||
};
|
||||
|
||||
template <typename Sequence, typename Indices>
|
||||
constexpr auto sliced(Sequence& sequence, Indices const& indices) {
|
||||
return hana::unpack(indices, [&](auto ...i) {
|
||||
return sliced_view_t<Sequence, decltype(i)::value...>{sequence};
|
||||
});
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename Sequence, std::size_t ...i>
|
||||
struct is_view<sliced_view_t<Sequence, i...>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// transformed_view
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename Sequence, typename F>
|
||||
struct transformed_view_t {
|
||||
detail::view_storage<Sequence> sequence_;
|
||||
F f_;
|
||||
using hana_tag = view_tag;
|
||||
};
|
||||
|
||||
template <typename Sequence, typename F>
|
||||
constexpr transformed_view_t<Sequence, typename hana::detail::decay<F>::type>
|
||||
transformed(Sequence& sequence, F&& f) {
|
||||
return {sequence, static_cast<F&&>(f)};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename Sequence, typename F>
|
||||
struct is_view<transformed_view_t<Sequence, F>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// filtered_view
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
#if 0
|
||||
template <typename Sequence, typename Pred>
|
||||
using filtered_view_t = sliced_view_t<Sequence, detail::filtered_indices<...>>;
|
||||
|
||||
template <typename Sequence, typename Pred>
|
||||
constexpr filtered_view_t<Sequence, Pred> filtered(Sequence& sequence, Pred&& pred) {
|
||||
return {sequence};
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// joined_view
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename Sequence1, typename Sequence2>
|
||||
struct joined_view_t {
|
||||
detail::view_storage<Sequence1> sequence1_;
|
||||
detail::view_storage<Sequence2> sequence2_;
|
||||
using hana_tag = view_tag;
|
||||
};
|
||||
|
||||
struct make_joined_view_t {
|
||||
template <typename Sequence1, typename Sequence2>
|
||||
constexpr joined_view_t<Sequence1, Sequence2> operator()(Sequence1& s1, Sequence2& s2) const {
|
||||
return {s1, s2};
|
||||
}
|
||||
};
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_joined_view_t joined{};
|
||||
|
||||
namespace detail {
|
||||
template <typename Sequence1, typename Sequence2>
|
||||
struct is_view<joined_view_t<Sequence1, Sequence2>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// single_view
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct single_view_t {
|
||||
T value_;
|
||||
using hana_tag = view_tag;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
constexpr single_view_t<typename hana::detail::decay<T>::type> single_view(T&& t) {
|
||||
return {static_cast<T&&>(t)};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct is_view<single_view_t<T>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// empty_view
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
struct empty_view_t {
|
||||
using hana_tag = view_tag;
|
||||
};
|
||||
|
||||
constexpr empty_view_t empty_view() {
|
||||
return {};
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template <>
|
||||
struct is_view<empty_view_t> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
} // end namespace experimental
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct unpack_impl<experimental::view_tag> {
|
||||
// sliced_view
|
||||
template <typename Sequence, std::size_t ...i, typename F>
|
||||
static constexpr decltype(auto)
|
||||
apply(experimental::sliced_view_t<Sequence, i...> view, F&& f) {
|
||||
(void)view; // Remove spurious unused variable warning with GCC
|
||||
return static_cast<F&&>(f)(hana::at_c<i>(view.sequence_)...);
|
||||
}
|
||||
|
||||
// transformed_view
|
||||
template <typename Sequence, typename F, typename G>
|
||||
static constexpr decltype(auto)
|
||||
apply(experimental::transformed_view_t<Sequence, F> view, G&& g) {
|
||||
return hana::unpack(view.sequence_, hana::on(static_cast<G&&>(g), view.f_));
|
||||
}
|
||||
|
||||
// joined_view
|
||||
template <typename View, typename F, std::size_t ...i1, std::size_t ...i2>
|
||||
static constexpr decltype(auto)
|
||||
unpack_joined(View view, F&& f, std::index_sequence<i1...>,
|
||||
std::index_sequence<i2...>)
|
||||
{
|
||||
(void)view; // Remove spurious unused variable warning with GCC
|
||||
return static_cast<F&&>(f)(hana::at_c<i1>(view.sequence1_)...,
|
||||
hana::at_c<i2>(view.sequence2_)...);
|
||||
}
|
||||
|
||||
template <typename S1, typename S2, typename F>
|
||||
static constexpr decltype(auto)
|
||||
apply(experimental::joined_view_t<S1, S2> view, F&& f) {
|
||||
constexpr auto N1 = decltype(hana::length(view.sequence1_))::value;
|
||||
constexpr auto N2 = decltype(hana::length(view.sequence2_))::value;
|
||||
return unpack_joined(view, static_cast<F&&>(f),
|
||||
std::make_index_sequence<N1>{},
|
||||
std::make_index_sequence<N2>{});
|
||||
}
|
||||
|
||||
// single_view
|
||||
template <typename T, typename F>
|
||||
static constexpr decltype(auto) apply(experimental::single_view_t<T> view, F&& f) {
|
||||
return static_cast<F&&>(f)(view.value_);
|
||||
}
|
||||
|
||||
// empty_view
|
||||
template <typename F>
|
||||
static constexpr decltype(auto) apply(experimental::empty_view_t, F&& f) {
|
||||
return static_cast<F&&>(f)();
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct at_impl<experimental::view_tag> {
|
||||
// sliced_view
|
||||
template <typename Sequence, std::size_t ...i, typename N>
|
||||
static constexpr decltype(auto)
|
||||
apply(experimental::sliced_view_t<Sequence, i...> view, N const&) {
|
||||
constexpr std::size_t indices[] = {i...};
|
||||
constexpr std::size_t n = indices[N::value];
|
||||
return hana::at_c<n>(view.sequence_);
|
||||
}
|
||||
|
||||
// transformed_view
|
||||
template <typename Sequence, typename F, typename N>
|
||||
static constexpr decltype(auto)
|
||||
apply(experimental::transformed_view_t<Sequence, F> view, N const& n) {
|
||||
return view.f_(hana::at(view.sequence_, n));
|
||||
}
|
||||
|
||||
// joined_view
|
||||
template <std::size_t Left, typename View, typename N>
|
||||
static constexpr decltype(auto) at_joined_view(View view, N const&, hana::true_) {
|
||||
return hana::at_c<N::value>(view.sequence1_);
|
||||
}
|
||||
|
||||
template <std::size_t Left, typename View, typename N>
|
||||
static constexpr decltype(auto) at_joined_view(View view, N const&, hana::false_) {
|
||||
return hana::at_c<N::value - Left>(view.sequence2_);
|
||||
}
|
||||
|
||||
template <typename S1, typename S2, typename N>
|
||||
static constexpr decltype(auto)
|
||||
apply(experimental::joined_view_t<S1, S2> view, N const& n) {
|
||||
constexpr auto Left = decltype(hana::length(view.sequence1_))::value;
|
||||
return at_joined_view<Left>(view, n, hana::bool_c<(N::value < Left)>);
|
||||
}
|
||||
|
||||
// single_view
|
||||
template <typename T, typename N>
|
||||
static constexpr decltype(auto) apply(experimental::single_view_t<T> view, N const&) {
|
||||
static_assert(N::value == 0,
|
||||
"trying to fetch an out-of-bounds element in a hana::single_view");
|
||||
return view.value_;
|
||||
}
|
||||
|
||||
// empty_view
|
||||
template <typename N>
|
||||
static constexpr decltype(auto) apply(experimental::empty_view_t, N const&) = delete;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct length_impl<experimental::view_tag> {
|
||||
// sliced_view
|
||||
template <typename Sequence, std::size_t ...i>
|
||||
static constexpr auto
|
||||
apply(experimental::sliced_view_t<Sequence, i...>) {
|
||||
return hana::size_c<sizeof...(i)>;
|
||||
}
|
||||
|
||||
// transformed_view
|
||||
template <typename Sequence, typename F>
|
||||
static constexpr auto apply(experimental::transformed_view_t<Sequence, F> view) {
|
||||
return hana::length(view.sequence_);
|
||||
}
|
||||
|
||||
// joined_view
|
||||
template <typename S1, typename S2>
|
||||
static constexpr auto apply(experimental::joined_view_t<S1, S2> view) {
|
||||
return hana::size_c<
|
||||
decltype(hana::length(view.sequence1_))::value +
|
||||
decltype(hana::length(view.sequence2_))::value
|
||||
>;
|
||||
}
|
||||
|
||||
// single_view
|
||||
template <typename T>
|
||||
static constexpr auto apply(experimental::single_view_t<T>) {
|
||||
return hana::size_c<1>;
|
||||
}
|
||||
|
||||
// empty_view
|
||||
static constexpr auto apply(experimental::empty_view_t) {
|
||||
return hana::size_c<0>;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_empty_impl<experimental::view_tag> {
|
||||
// sliced_view
|
||||
template <typename Sequence, std::size_t ...i>
|
||||
static constexpr auto
|
||||
apply(experimental::sliced_view_t<Sequence, i...>) {
|
||||
return hana::bool_c<sizeof...(i) == 0>;
|
||||
}
|
||||
|
||||
// transformed_view
|
||||
template <typename Sequence, typename F>
|
||||
static constexpr auto apply(experimental::transformed_view_t<Sequence, F> view) {
|
||||
return hana::is_empty(view.sequence_);
|
||||
}
|
||||
|
||||
// joined_view
|
||||
template <typename S1, typename S2>
|
||||
static constexpr auto apply(experimental::joined_view_t<S1, S2> view) {
|
||||
return hana::and_(hana::is_empty(view.sequence1_),
|
||||
hana::is_empty(view.sequence2_));
|
||||
}
|
||||
|
||||
// single_view
|
||||
template <typename T>
|
||||
static constexpr auto apply(experimental::single_view_t<T>) {
|
||||
return hana::false_c;
|
||||
}
|
||||
|
||||
// empty_view
|
||||
static constexpr auto apply(experimental::empty_view_t) {
|
||||
return hana::true_c;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct drop_front_impl<experimental::view_tag> {
|
||||
template <typename View, typename N>
|
||||
static constexpr auto apply(View view, N const&) {
|
||||
constexpr auto n = N::value;
|
||||
constexpr auto Length = decltype(hana::length(view))::value;
|
||||
return experimental::sliced(view, hana::range_c<std::size_t, n, Length>);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Functor
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct transform_impl<experimental::view_tag> {
|
||||
template <typename Sequence, typename F, typename G>
|
||||
static constexpr auto
|
||||
apply(experimental::transformed_view_t<Sequence, F> view, G&& g) {
|
||||
return experimental::transformed(view.sequence_,
|
||||
hana::compose(static_cast<G&&>(g), view.f_));
|
||||
}
|
||||
|
||||
template <typename View, typename F>
|
||||
static constexpr auto apply(View view, F&& f) {
|
||||
return experimental::transformed(view, static_cast<F&&>(f));
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Applicative
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct lift_impl<experimental::view_tag> {
|
||||
template <typename T>
|
||||
static constexpr auto apply(T&& t) {
|
||||
return experimental::single_view(static_cast<T&&>(t));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct ap_impl<experimental::view_tag> {
|
||||
template <typename F, typename X>
|
||||
static constexpr auto apply(F&& f, X&& x) {
|
||||
// TODO: Implement cleverly; we most likely need a cartesian_product
|
||||
// view or something like that.
|
||||
return hana::ap(hana::to_tuple(f), hana::to_tuple(x));
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Monad
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct flatten_impl<experimental::view_tag> {
|
||||
template <typename View>
|
||||
static constexpr auto apply(View view) {
|
||||
// TODO: Implement a flattened_view instead
|
||||
return hana::fold_left(view, experimental::empty_view(),
|
||||
experimental::joined);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MonadPlus
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct concat_impl<experimental::view_tag> {
|
||||
template <typename View1, typename View2>
|
||||
static constexpr auto apply(View1 view1, View2 view2) {
|
||||
return experimental::joined(view1, view2);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct empty_impl<experimental::view_tag> {
|
||||
static constexpr auto apply() {
|
||||
return experimental::empty_view();
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Comparable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct equal_impl<experimental::view_tag, experimental::view_tag> {
|
||||
template <typename View1, typename View2>
|
||||
static constexpr auto apply(View1 v1, View2 v2) {
|
||||
// TODO: Use a lexicographical comparison algorithm.
|
||||
return hana::equal(hana::to_tuple(v1), hana::to_tuple(v2));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct equal_impl<experimental::view_tag, S, hana::when<hana::Sequence<S>::value>> {
|
||||
template <typename View1, typename Seq>
|
||||
static constexpr auto apply(View1 v1, Seq const& s) {
|
||||
// TODO: Use a lexicographical comparison algorithm.
|
||||
return hana::equal(hana::to_tuple(v1), hana::to_tuple(s));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct equal_impl<S, experimental::view_tag, hana::when<hana::Sequence<S>::value>> {
|
||||
template <typename Seq, typename View2>
|
||||
static constexpr auto apply(Seq const& s, View2 v2) {
|
||||
// TODO: Use a lexicographical comparison algorithm.
|
||||
return hana::equal(hana::to_tuple(s), hana::to_tuple(v2));
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Orderable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct less_impl<experimental::view_tag, experimental::view_tag> {
|
||||
template <typename View1, typename View2>
|
||||
static constexpr auto apply(View1 v1, View2 v2) {
|
||||
return hana::lexicographical_compare(v1, v2);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct less_impl<experimental::view_tag, S, hana::when<hana::Sequence<S>::value>> {
|
||||
template <typename View1, typename Seq>
|
||||
static constexpr auto apply(View1 v1, Seq const& s) {
|
||||
return hana::lexicographical_compare(v1, s);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct less_impl<S, experimental::view_tag, hana::when<hana::Sequence<S>::value>> {
|
||||
template <typename Seq, typename View2>
|
||||
static constexpr auto apply(Seq const& s, View2 v2) {
|
||||
return hana::lexicographical_compare(s, v2);
|
||||
}
|
||||
};
|
||||
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXPERIMENTAL_VIEW_HPP
|
21
_deps/boost-src/libs/hana/include/boost/hana/ext/boost.hpp
Normal file
21
_deps/boost-src/libs/hana/include/boost/hana/ext/boost.hpp
Normal file
@ -0,0 +1,21 @@
|
||||
/*!
|
||||
@file
|
||||
Includes all the adaptors for external Boost libraries.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_HPP
|
||||
|
||||
//! @ingroup group-ext
|
||||
//! @defgroup group-ext-boost Other Boost adapters
|
||||
//! Adapters for miscellaneous heterogeneous containers in Boost.
|
||||
|
||||
#include <boost/hana/ext/boost/fusion.hpp>
|
||||
#include <boost/hana/ext/boost/mpl.hpp>
|
||||
#include <boost/hana/ext/boost/tuple.hpp>
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_HPP
|
@ -0,0 +1,22 @@
|
||||
/*!
|
||||
@file
|
||||
Includes all the adaptors for the Boost.Fusion library.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_FUSION_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_FUSION_HPP
|
||||
|
||||
//! @ingroup group-ext
|
||||
//! @defgroup group-ext-fusion Boost.Fusion adapters
|
||||
//! Adapters for Boost.Fusion containers.
|
||||
|
||||
#include <boost/hana/ext/boost/fusion/deque.hpp>
|
||||
#include <boost/hana/ext/boost/fusion/list.hpp>
|
||||
#include <boost/hana/ext/boost/fusion/tuple.hpp>
|
||||
#include <boost/hana/ext/boost/fusion/vector.hpp>
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_FUSION_HPP
|
@ -0,0 +1,108 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `boost::fusion::deque` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_FUSION_DEQUE_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_FUSION_DEQUE_HPP
|
||||
|
||||
#include <boost/hana/at.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/ext/boost/fusion/detail/common.hpp>
|
||||
#include <boost/hana/fwd/core/make.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
#include <boost/hana/length.hpp>
|
||||
|
||||
#include <boost/fusion/container/deque.hpp>
|
||||
#include <boost/fusion/container/generation/make_deque.hpp>
|
||||
#include <boost/fusion/support/tag_of.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace boost { namespace fusion {
|
||||
//! @ingroup group-ext-fusion
|
||||
//! Adapter for Boost.Fusion deques.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! A Fusion deque is a model of the `Sequence` concept, and all the
|
||||
//! concepts it refines. That makes it essentially the same as a Hana
|
||||
//! tuple, although the complexity of some operations might differ from
|
||||
//! that of a tuple.
|
||||
//!
|
||||
//! @include example/ext/boost/fusion/deque.cpp
|
||||
template <typename ...T>
|
||||
struct deque { };
|
||||
}}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace boost { namespace fusion {
|
||||
struct deque_tag;
|
||||
}}}
|
||||
|
||||
template <typename T>
|
||||
struct tag_of<T, when<
|
||||
std::is_same<
|
||||
typename ::boost::fusion::traits::tag_of<T>::type,
|
||||
::boost::fusion::traits::tag_of<
|
||||
::boost::fusion::deque<>
|
||||
>::type
|
||||
>::value
|
||||
>> {
|
||||
using type = ext::boost::fusion::deque_tag;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <>
|
||||
struct is_fusion_sequence<ext::boost::fusion::deque_tag> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable (the rest is in detail/common.hpp)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct drop_front_impl<ext::boost::fusion::deque_tag> {
|
||||
template <std::size_t n, typename Xs, std::size_t ...i>
|
||||
static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
|
||||
return hana::make<ext::boost::fusion::deque_tag>(
|
||||
hana::at_c<n + i>(static_cast<Xs&&>(xs))...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr std::size_t len = decltype(hana::length(xs))::value;
|
||||
return drop_front_helper<n>(static_cast<Xs&&>(xs),
|
||||
std::make_index_sequence<(n < len ? len - n : 0)>{});
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sequence
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct make_impl<ext::boost::fusion::deque_tag> {
|
||||
template <typename ...Xs>
|
||||
static constexpr auto apply(Xs&& ...xs) {
|
||||
return ::boost::fusion::make_deque(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_FUSION_DEQUE_HPP
|
@ -0,0 +1,79 @@
|
||||
/*!
|
||||
@file
|
||||
Defines common methods for all Boost.Fusion sequences.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_FUSION_DETAIL_COMMON_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_FUSION_DETAIL_COMMON_HPP
|
||||
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/concept/sequence.hpp>
|
||||
#include <boost/hana/fwd/is_empty.hpp>
|
||||
#include <boost/hana/fwd/length.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
|
||||
#include <boost/fusion/sequence/intrinsic/at.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/empty.hpp>
|
||||
#include <boost/fusion/sequence/intrinsic/size.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct is_fusion_sequence {
|
||||
static constexpr bool value = false;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename S>
|
||||
struct at_impl<S, when<detail::is_fusion_sequence<S>::value>> {
|
||||
template <typename Xs, typename N>
|
||||
static constexpr decltype(auto) apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
return boost::fusion::at_c<n>(static_cast<Xs&&>(xs));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct is_empty_impl<S, when<detail::is_fusion_sequence<S>::value>> {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs&& xs) {
|
||||
using Empty = decltype(boost::fusion::empty(xs));
|
||||
return hana::bool_c<Empty::value>;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename S>
|
||||
struct length_impl<S, when<detail::is_fusion_sequence<S>::value>> {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs const&) {
|
||||
using Size = typename boost::fusion::result_of::size<Xs>::type;
|
||||
return hana::size_c<Size::value>;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sequence
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename S>
|
||||
struct Sequence<S, when<detail::is_fusion_sequence<S>::value>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_FUSION_DETAIL_COMMON_HPP
|
@ -0,0 +1,111 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `boost::fusion::list` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_FUSION_LIST_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_FUSION_LIST_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/ext/boost/fusion/detail/common.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/core/make.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
#include <boost/hana/fwd/length.hpp>
|
||||
|
||||
#include <boost/fusion/algorithm/transformation/pop_front.hpp>
|
||||
#include <boost/fusion/container/generation/make_list.hpp>
|
||||
#include <boost/fusion/container/list.hpp>
|
||||
#include <boost/fusion/container/list/convert.hpp>
|
||||
#include <boost/fusion/support/tag_of.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace boost { namespace fusion {
|
||||
//! @ingroup group-ext-fusion
|
||||
//! Adapter for Boost.Fusion lists.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! A Fusion list is a model of the `Sequence` concept, and all the
|
||||
//! concepts it refines. That makes it essentially the same as a Hana
|
||||
//! tuple, although the complexity of some operations might differ from
|
||||
//! that of a tuple.
|
||||
//!
|
||||
//! @include example/ext/boost/fusion/list.cpp
|
||||
template <typename ...T>
|
||||
struct list { };
|
||||
}}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace boost { namespace fusion {
|
||||
struct list_tag;
|
||||
}}}
|
||||
|
||||
template <typename T>
|
||||
struct tag_of<T, when<
|
||||
std::is_same<
|
||||
typename ::boost::fusion::traits::tag_of<T>::type,
|
||||
::boost::fusion::traits::tag_of<
|
||||
::boost::fusion::list<>
|
||||
>::type
|
||||
>::value
|
||||
>> {
|
||||
using type = ext::boost::fusion::list_tag;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <>
|
||||
struct is_fusion_sequence<ext::boost::fusion::list_tag> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable (the rest is in detail/common.hpp)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct drop_front_impl<ext::boost::fusion::list_tag> {
|
||||
template <std::size_t n, typename Xs, std::size_t ...i>
|
||||
static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
|
||||
return hana::make<ext::boost::fusion::list_tag>(
|
||||
hana::at_c<n + i>(static_cast<Xs&&>(xs))...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr std::size_t len = decltype(hana::length(xs))::value;
|
||||
return drop_front_helper<n>(static_cast<Xs&&>(xs),
|
||||
std::make_index_sequence<(n < len ? len - n : 0)>{});
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sequence
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct make_impl<ext::boost::fusion::list_tag> {
|
||||
template <typename ...Xs>
|
||||
static constexpr auto apply(Xs&& ...xs) {
|
||||
return ::boost::fusion::make_list(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_FUSION_LIST_HPP
|
@ -0,0 +1,49 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `boost::fusion::tuple` for use with Hana.
|
||||
|
||||
In the current version of Boost.Fusion, `boost::fusion::tuple` is basically
|
||||
an alias to `boost::fusion::vector`, so both data types share the same
|
||||
implementation in Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_FUSION_TUPLE_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_FUSION_TUPLE_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/ext/boost/fusion/vector.hpp>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace boost { namespace fusion {
|
||||
//! @ingroup group-ext-fusion
|
||||
//! Adapter for Boost.Fusion tuples.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! A Fusion tuple is a model of the `Sequence` concept, and all the
|
||||
//! concepts it refines. That makes it essentially the same as a Hana
|
||||
//! tuple, although the complexity of some operations might differ from
|
||||
//! that of a tuple.
|
||||
//!
|
||||
//! @include example/ext/boost/fusion/tuple.cpp
|
||||
template <typename ...T>
|
||||
struct tuple { };
|
||||
}}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace boost { namespace fusion {
|
||||
// In the current version of Boost.Fusion, `boost::fusion::tuple` is
|
||||
// basically an alias to `boost::fusion::vector`, hence the alias.
|
||||
using tuple_tag = vector_tag;
|
||||
}}}
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_FUSION_TUPLE_HPP
|
@ -0,0 +1,110 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `boost::fusion::vector` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_FUSION_VECTOR_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_FUSION_VECTOR_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/ext/boost/fusion/detail/common.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/core/make.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
#include <boost/hana/fwd/length.hpp>
|
||||
|
||||
#include <boost/fusion/algorithm/transformation/pop_front.hpp>
|
||||
#include <boost/fusion/container/generation/make_vector.hpp>
|
||||
#include <boost/fusion/container/vector.hpp>
|
||||
#include <boost/fusion/container/vector/convert.hpp>
|
||||
#include <boost/fusion/support/tag_of.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace boost { namespace fusion {
|
||||
//! @ingroup group-ext-fusion
|
||||
//! Adapter for Boost.Fusion vectors.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! A Fusion vector is a model of the `Sequence` concept, and all the
|
||||
//! concepts it refines. That makes it essentially the same as a Hana
|
||||
//! tuple, although the complexity of some operations might differ from
|
||||
//! that of a tuple.
|
||||
//!
|
||||
//! @include example/ext/boost/fusion/vector.cpp
|
||||
template <typename ...T>
|
||||
struct vector { };
|
||||
}}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace boost { namespace fusion {
|
||||
struct vector_tag;
|
||||
}}}
|
||||
|
||||
template <typename T>
|
||||
struct tag_of<T, when<
|
||||
std::is_same<
|
||||
typename ::boost::fusion::traits::tag_of<T>::type,
|
||||
::boost::fusion::traits::tag_of<
|
||||
::boost::fusion::vector<>
|
||||
>::type
|
||||
>::value
|
||||
>> {
|
||||
using type = ext::boost::fusion::vector_tag;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <>
|
||||
struct is_fusion_sequence<ext::boost::fusion::vector_tag> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable (the rest is in detail/common.hpp)
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct drop_front_impl<ext::boost::fusion::vector_tag> {
|
||||
template <std::size_t n, typename Xs, std::size_t ...i>
|
||||
static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
|
||||
return hana::make<ext::boost::fusion::vector_tag>(
|
||||
hana::at_c<n + i>(static_cast<Xs&&>(xs))...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr std::size_t len = decltype(hana::length(xs))::value;
|
||||
return drop_front_helper<n>(static_cast<Xs&&>(xs),
|
||||
std::make_index_sequence<(n < len ? len - n : 0)>{});
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sequence
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct make_impl<ext::boost::fusion::vector_tag> {
|
||||
template <typename ...Xs>
|
||||
static constexpr auto apply(Xs&& ...xs) {
|
||||
return ::boost::fusion::make_vector(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_FUSION_VECTOR_HPP
|
@ -0,0 +1,21 @@
|
||||
/*!
|
||||
@file
|
||||
Includes all the adaptors for the Boost.MPL library.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_MPL_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_MPL_HPP
|
||||
|
||||
//! @ingroup group-ext
|
||||
//! @defgroup group-ext-mpl Boost.MPL adapters
|
||||
//! Adapters for Boost.MPL containers.
|
||||
|
||||
#include <boost/hana/ext/boost/mpl/integral_c.hpp>
|
||||
#include <boost/hana/ext/boost/mpl/list.hpp>
|
||||
#include <boost/hana/ext/boost/mpl/vector.hpp>
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_MPL_HPP
|
@ -0,0 +1,81 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts Boost.MPL IntegralConstants for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_MPL_INTEGRAL_C_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_MPL_INTEGRAL_C_HPP
|
||||
|
||||
#include <boost/hana/concept/integral_constant.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/tag_of.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/fwd/core/to.hpp>
|
||||
|
||||
#include <boost/mpl/integral_c.hpp>
|
||||
#include <boost/mpl/integral_c_tag.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace boost { namespace mpl {
|
||||
//! @ingroup group-ext-mpl
|
||||
//! Adapter for IntegralConstants from the Boost.MPL.
|
||||
//!
|
||||
//! Provided models
|
||||
//! ---------------
|
||||
//! 1. `Constant` and `IntegralConstant`\n
|
||||
//! A Boost.MPL IntegralConstant is a model of the `IntegralConstant`
|
||||
//! and `Constant` concepts just like `hana::integral_constant`s are.
|
||||
//! As a consequence, they are also implicitly a model of the concepts
|
||||
//! provided for all models of `Constant`.
|
||||
//! @include example/ext/boost/mpl/integral_c/integral_constant.cpp
|
||||
template <typename T, T v>
|
||||
struct integral_c { };
|
||||
}}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace boost { namespace mpl {
|
||||
template <typename T>
|
||||
struct integral_c_tag { using value_type = T; };
|
||||
}}}
|
||||
|
||||
template <typename T>
|
||||
struct tag_of<T, when<
|
||||
std::is_same<
|
||||
typename T::tag,
|
||||
::boost::mpl::integral_c_tag
|
||||
>::value
|
||||
>> {
|
||||
using type = ext::boost::mpl::integral_c_tag<
|
||||
typename hana::tag_of<typename T::value_type>::type
|
||||
>;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// IntegralConstant/Constant
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct IntegralConstant<ext::boost::mpl::integral_c_tag<T>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template <typename T, typename C>
|
||||
struct to_impl<ext::boost::mpl::integral_c_tag<T>, C,
|
||||
when<hana::IntegralConstant<C>::value>
|
||||
> : embedding<is_embedded<typename C::value_type, T>::value> {
|
||||
template <typename N>
|
||||
static constexpr auto apply(N const&) {
|
||||
return ::boost::mpl::integral_c<T, N::value>{};
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_MPL_INTEGRAL_C_HPP
|
@ -0,0 +1,186 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `boost::mpl::list` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_MPL_LIST_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_MPL_LIST_HPP
|
||||
|
||||
#include <boost/hana/concept/foldable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/ext/boost/mpl/integral_c.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/core/to.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
#include <boost/hana/fwd/equal.hpp>
|
||||
#include <boost/hana/fwd/is_empty.hpp>
|
||||
#include <boost/hana/fwd/less.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
#include <boost/hana/length.hpp>
|
||||
#include <boost/hana/type.hpp>
|
||||
#include <boost/hana/unpack.hpp>
|
||||
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/empty.hpp>
|
||||
#include <boost/mpl/equal.hpp>
|
||||
#include <boost/mpl/list.hpp>
|
||||
#include <boost/mpl/sequence_tag.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace boost { namespace mpl {
|
||||
//! @ingroup group-ext-mpl
|
||||
//! Adapter for Boost.MPL lists.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! It is possible for MPL lists to model a couple of concepts.
|
||||
//! However, because they are only able to hold types, they lack
|
||||
//! the generality required to model concepts like `Functor`,
|
||||
//! `Sequence` and other related concepts.
|
||||
//!
|
||||
//! 1. `Comparable`\n
|
||||
//! Two MPL lists are equal if and only if they contain the same
|
||||
//! number of types, and if all those types are equal.
|
||||
//! @include example/ext/boost/mpl/list/comparable.cpp
|
||||
//!
|
||||
//! 2. `Foldable`\n
|
||||
//! Folding a MPL list is equivalent to folding it as a `Sequence`.
|
||||
//! @include example/ext/boost/mpl/list/foldable.cpp
|
||||
//!
|
||||
//! 3. `Iterable`\n
|
||||
//! Iterating over a MPL list is just iterating over each of the
|
||||
//! types it contains, as if it were a `Sequence`.
|
||||
//! @include example/ext/boost/mpl/list/iterable.cpp
|
||||
//!
|
||||
//! 4. `Searchable`\n
|
||||
//! A MPL list can be searched as if it were a tuple containing
|
||||
//! `hana::type`s.
|
||||
//! @include example/ext/boost/mpl/list/searchable.cpp
|
||||
//!
|
||||
//!
|
||||
//! Conversion from any `Foldable`
|
||||
//! ------------------------------
|
||||
//! A MPL list can be created from any `Foldable`. More precisely,
|
||||
//! for a `Foldable` `xs` whose linearization is `[x1, ..., xn]`,
|
||||
//! @code
|
||||
//! to<ext::boost::mpl::list_tag>(xs) == mpl::list<t1, ..., tn>{}
|
||||
//! @endcode
|
||||
//! where `tk` is the type of `xk`, or the type contained in `xk` if
|
||||
//! `xk` is a `hana::type`.
|
||||
//! @warning
|
||||
//! The limitations on the size of `mpl::list`s are inherited by
|
||||
//! this conversion utility, and hence trying to convert a `Foldable`
|
||||
//! containing more than [BOOST_MPL_LIMIT_LIST_SIZE][1] elements is
|
||||
//! an error.
|
||||
//! @include example/ext/boost/mpl/list/conversion.cpp
|
||||
//!
|
||||
//! [1]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/limit-list-size.html
|
||||
template <typename ...T>
|
||||
struct list { };
|
||||
}}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace boost { namespace mpl {
|
||||
using list_tag = ::boost::mpl::sequence_tag< ::boost::mpl::list<>>::type;
|
||||
}}}
|
||||
|
||||
template <typename T>
|
||||
struct tag_of<T, when<
|
||||
std::is_same<
|
||||
typename ::boost::mpl::sequence_tag<T>::type,
|
||||
::boost::mpl::sequence_tag< ::boost::mpl::list<>>::type
|
||||
>::value
|
||||
>> {
|
||||
using type = ext::boost::mpl::list_tag;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Comparable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct equal_impl<ext::boost::mpl::list_tag, ext::boost::mpl::list_tag> {
|
||||
template <typename Xs, typename Ys>
|
||||
static constexpr auto apply(Xs const&, Ys const&) {
|
||||
return typename ::boost::mpl::equal<Xs, Ys>::type{};
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct length_impl<ext::boost::mpl::list_tag> {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs const&) {
|
||||
return hana::size_c< ::boost::mpl::size<Xs>::type::value>;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct at_impl<ext::boost::mpl::list_tag> {
|
||||
template <typename Ts, typename N>
|
||||
static constexpr auto apply(Ts const&, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
using T = typename ::boost::mpl::at_c<Ts, n>::type;
|
||||
return hana::type_c<T>;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct drop_front_impl<ext::boost::mpl::list_tag> {
|
||||
template <std::size_t n, typename Xs, std::size_t ...i>
|
||||
static constexpr auto drop_front_helper(Xs const&, std::index_sequence<i...>) {
|
||||
return boost::mpl::list<
|
||||
typename boost::mpl::at_c<Xs, n + i>::type...
|
||||
>{};
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs const& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr std::size_t len = decltype(hana::length(xs))::value;
|
||||
return drop_front_helper<n>(xs,
|
||||
std::make_index_sequence<(n < len ? len - n : 0)>{});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_empty_impl<ext::boost::mpl::list_tag> {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs const&)
|
||||
{ return typename ::boost::mpl::empty<Xs>::type{}; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Conversion from a Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename F>
|
||||
struct to_impl<ext::boost::mpl::list_tag, F, when<hana::Foldable<F>::value>> {
|
||||
template <typename Xs>
|
||||
static constexpr decltype(auto) apply(Xs&& xs) {
|
||||
auto list_type = hana::unpack(static_cast<Xs&&>(xs),
|
||||
hana::template_<::boost::mpl::list>);
|
||||
return typename decltype(list_type)::type{};
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_MPL_LIST_HPP
|
@ -0,0 +1,201 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `boost::mpl::vector` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_MPL_VECTOR_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_MPL_VECTOR_HPP
|
||||
|
||||
#include <boost/hana/concept/foldable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/ext/boost/mpl/integral_c.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/core/to.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
#include <boost/hana/fwd/equal.hpp>
|
||||
#include <boost/hana/fwd/is_empty.hpp>
|
||||
#include <boost/hana/fwd/less.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
#include <boost/hana/length.hpp>
|
||||
#include <boost/hana/type.hpp>
|
||||
#include <boost/hana/unpack.hpp>
|
||||
|
||||
#include <boost/mpl/at.hpp>
|
||||
#include <boost/mpl/empty.hpp>
|
||||
#include <boost/mpl/equal.hpp>
|
||||
#include <boost/mpl/sequence_tag.hpp>
|
||||
#include <boost/mpl/size.hpp>
|
||||
#include <boost/mpl/vector.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace boost { namespace mpl {
|
||||
//! @ingroup group-ext-mpl
|
||||
//! Adapter for Boost.MPL vectors.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! It is possible for MPL vectors to model a couple of concepts.
|
||||
//! However, because they are only able to hold types, they lack
|
||||
//! the generality required to model concepts like `Functor`,
|
||||
//! `Sequence` and other related concepts.
|
||||
//!
|
||||
//! 1. `Comparable`\n
|
||||
//! Two MPL vectors are equal if and only if they contain the same
|
||||
//! number of types, and if all those types are equal.
|
||||
//! @include example/ext/boost/mpl/vector/comparable.cpp
|
||||
//!
|
||||
//! 2. `Foldable`\n
|
||||
//! Folding a MPL vector is equivalent to folding it as a `Sequence`.
|
||||
//! @include example/ext/boost/mpl/vector/foldable.cpp
|
||||
//!
|
||||
//! 3. `Iterable`\n
|
||||
//! Iterating over a MPL vector is just iterating over each of the
|
||||
//! types it contains, as if it were a `Sequence`.
|
||||
//! @include example/ext/boost/mpl/vector/iterable.cpp
|
||||
//!
|
||||
//! 4. `Searchable`\n
|
||||
//! A MPL vector can be searched as if it were a tuple containing
|
||||
//! `hana::type`s.
|
||||
//! @include example/ext/boost/mpl/vector/searchable.cpp
|
||||
//!
|
||||
//!
|
||||
//! Conversion from any `Foldable`
|
||||
//! ------------------------------
|
||||
//! A MPL vector can be created from any `Foldable`. More precisely,
|
||||
//! for a `Foldable` `xs` whose linearization is `[x1, ..., xn]`,
|
||||
//! @code
|
||||
//! to<ext::boost::mpl::vector_tag>(xs) == mpl::vector<t1, ..., tn>
|
||||
//! @endcode
|
||||
//! where `tk` is the type of `xk`, or the type contained in `xk` if
|
||||
//! `xk` is a `hana::type`.
|
||||
//! @warning
|
||||
//! The limitations on the size of `mpl::vector`s are inherited by
|
||||
//! this conversion utility, and hence trying to convert a `Foldable`
|
||||
//! containing more than [BOOST_MPL_LIMIT_VECTOR_SIZE][1] elements
|
||||
//! is an error.
|
||||
//! @include example/ext/boost/mpl/vector/conversion.cpp
|
||||
//!
|
||||
//! [1]: http://www.boost.org/doc/libs/release/libs/mpl/doc/refmanual/limit-vector-size.html
|
||||
template <typename ...T>
|
||||
struct vector { };
|
||||
}}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace boost { namespace mpl {
|
||||
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<
|
||||
mpl_detail::is_same_mpl_vector_tag<
|
||||
typename ::boost::mpl::sequence_tag<T>::type,
|
||||
::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type
|
||||
>::value
|
||||
>> {
|
||||
using type = ext::boost::mpl::vector_tag;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Comparable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct equal_impl<ext::boost::mpl::vector_tag, ext::boost::mpl::vector_tag> {
|
||||
template <typename Xs, typename Ys>
|
||||
static constexpr auto apply(Xs const&, Ys const&) {
|
||||
return typename ::boost::mpl::equal<Xs, Ys>::type{};
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct length_impl<ext::boost::mpl::vector_tag> {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs const&) {
|
||||
return hana::size_c< ::boost::mpl::size<Xs>::type::value>;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct at_impl<ext::boost::mpl::vector_tag> {
|
||||
template <typename Ts, typename N>
|
||||
static constexpr auto apply(Ts const&, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
using T = typename ::boost::mpl::at_c<Ts, n>::type;
|
||||
return hana::type_c<T>;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct drop_front_impl<ext::boost::mpl::vector_tag> {
|
||||
template <std::size_t n, typename Xs, std::size_t ...i>
|
||||
static constexpr auto drop_front_helper(Xs const&, std::index_sequence<i...>) {
|
||||
return boost::mpl::vector<
|
||||
typename boost::mpl::at_c<Xs, n + i>::type...
|
||||
>{};
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs const& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr std::size_t len = decltype(hana::length(xs))::value;
|
||||
return drop_front_helper<n>(xs,
|
||||
std::make_index_sequence<(n < len ? len - n : 0)>{});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_empty_impl<ext::boost::mpl::vector_tag> {
|
||||
template <typename xs>
|
||||
static constexpr auto apply(xs)
|
||||
{ return typename ::boost::mpl::empty<xs>::type{}; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Conversion from a Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename F>
|
||||
struct to_impl<ext::boost::mpl::vector_tag, F, when<hana::Foldable<F>::value>> {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs const& xs) {
|
||||
auto vector_type = hana::unpack(xs, hana::template_<boost::mpl::vector>);
|
||||
return typename decltype(vector_type)::type{};
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_MPL_VECTOR_HPP
|
138
_deps/boost-src/libs/hana/include/boost/hana/ext/boost/tuple.hpp
Normal file
138
_deps/boost-src/libs/hana/include/boost/hana/ext/boost/tuple.hpp
Normal file
@ -0,0 +1,138 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `boost::tuple` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_BOOST_TUPLE_HPP
|
||||
#define BOOST_HANA_EXT_BOOST_TUPLE_HPP
|
||||
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/core/make.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
#include <boost/hana/fwd/is_empty.hpp>
|
||||
#include <boost/hana/fwd/length.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace boost {
|
||||
//! @ingroup group-ext-boost
|
||||
//! Adapter for `boost::tuple`s.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! A `boost::tuple` is a model of the `Sequence` concept, and all the
|
||||
//! concepts it refines. That makes it essentially the same as a Hana
|
||||
//! tuple, although the complexity of some operations might differ from
|
||||
//! that of Hana's tuple.
|
||||
//!
|
||||
//! @include example/ext/boost/tuple.cpp
|
||||
template <typename ...T>
|
||||
struct tuple { };
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace boost { struct tuple_tag; }}
|
||||
|
||||
template <typename ...Xs>
|
||||
struct tag_of<boost::tuple<Xs...>> {
|
||||
using type = ext::boost::tuple_tag;
|
||||
};
|
||||
|
||||
template <typename H, typename T>
|
||||
struct tag_of<boost::tuples::cons<H, T>> {
|
||||
using type = ext::boost::tuple_tag;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct tag_of<boost::tuples::null_type> {
|
||||
using type = ext::boost::tuple_tag;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct at_impl<ext::boost::tuple_tag> {
|
||||
template <typename Xs, typename N>
|
||||
static constexpr decltype(auto) apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
return static_cast<Xs&&>(xs).template get<n>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct drop_front_impl<ext::boost::tuple_tag> {
|
||||
template <std::size_t n, typename Xs, std::size_t ...i>
|
||||
static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
|
||||
return hana::make<ext::boost::tuple_tag>(
|
||||
hana::at_c<n + i>(static_cast<Xs&&>(xs))...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr std::size_t len = decltype(hana::length(xs))::value;
|
||||
return drop_front_helper<n>(static_cast<Xs&&>(xs),
|
||||
std::make_index_sequence<(n < len ? len - n : 0)>{});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_empty_impl<ext::boost::tuple_tag> {
|
||||
static constexpr auto apply(boost::tuples::null_type const&)
|
||||
{ return hana::true_c; }
|
||||
|
||||
template <typename H, typename T>
|
||||
static constexpr auto apply(boost::tuples::cons<H, T> const&)
|
||||
{ return hana::false_c; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct length_impl<ext::boost::tuple_tag> {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs const&) {
|
||||
return hana::size_c<boost::tuples::length<Xs>::value>;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sequence
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct Sequence<ext::boost::tuple_tag> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct make_impl<ext::boost::tuple_tag> {
|
||||
template <typename ...Xs>
|
||||
static constexpr auto apply(Xs&& ...xs) {
|
||||
return boost::tuples::tuple<
|
||||
typename detail::decay<Xs>::type...
|
||||
>{static_cast<Xs&&>(xs)...};
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_BOOST_TUPLE_HPP
|
25
_deps/boost-src/libs/hana/include/boost/hana/ext/std.hpp
Normal file
25
_deps/boost-src/libs/hana/include/boost/hana/ext/std.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
/*!
|
||||
@file
|
||||
Includes all the adaptors for the standard library.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_STD_HPP
|
||||
#define BOOST_HANA_EXT_STD_HPP
|
||||
|
||||
//! @ingroup group-ext
|
||||
//! @defgroup group-ext-std Standard library adapters
|
||||
//! Adapters for components in the standard library.
|
||||
|
||||
#include <boost/hana/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
|
171
_deps/boost-src/libs/hana/include/boost/hana/ext/std/array.hpp
Normal file
171
_deps/boost-src/libs/hana/include/boost/hana/ext/std/array.hpp
Normal file
@ -0,0 +1,171 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `std::array` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_STD_ARRAY_HPP
|
||||
#define BOOST_HANA_EXT_STD_ARRAY_HPP
|
||||
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/algorithm.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
#include <boost/hana/fwd/equal.hpp>
|
||||
#include <boost/hana/fwd/is_empty.hpp>
|
||||
#include <boost/hana/fwd/length.hpp>
|
||||
#include <boost/hana/fwd/less.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace std {
|
||||
//! @ingroup group-ext-std
|
||||
//! Adaptation of `std::array` for Hana.
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! 1. `Comparable`\n
|
||||
//! `std::array`s are compared as per `std::equal`, except that two arrays
|
||||
//! with different sizes compare unequal instead of triggering an error
|
||||
//! and the result of the comparison is `constexpr` if both arrays are
|
||||
//! `constexpr`.
|
||||
//! @include example/ext/std/array/comparable.cpp
|
||||
//!
|
||||
//! 2. `Orderable`\n
|
||||
//! `std::array`s are ordered with the usual lexicographical ordering,
|
||||
//! except that two arrays with different size can be ordered instead
|
||||
//! of triggering an error and the result of the comparison is `constexpr`
|
||||
//! if both arrays are `constexpr`.
|
||||
//! @include example/ext/std/array/orderable.cpp
|
||||
//!
|
||||
//! 3. `Foldable`\n
|
||||
//! Folding an array from the left is equivalent to calling
|
||||
//! `std::accumulate` on it, except it can be `constexpr`.
|
||||
//! @include example/ext/std/array/foldable.cpp
|
||||
//!
|
||||
//! 4. `Iterable`\n
|
||||
//! Iterating over a `std::array` is equivalent to iterating over it with
|
||||
//! a normal `for` loop.
|
||||
//! @include example/ext/std/array/iterable.cpp
|
||||
template <typename T, std::size_t N>
|
||||
struct array { };
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace std { struct array_tag; }}
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct tag_of<std::array<T, N>> {
|
||||
using type = ext::std::array_tag;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct length_impl<ext::std::array_tag> {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs const&) {
|
||||
return hana::size_c<std::tuple_size<Xs>::type::value>;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct at_impl<ext::std::array_tag> {
|
||||
template <typename Xs, typename N>
|
||||
static constexpr decltype(auto) apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
return std::get<n>(static_cast<Xs&&>(xs));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct drop_front_impl<ext::std::array_tag> {
|
||||
template <std::size_t n, typename Xs, std::size_t ...i>
|
||||
static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
|
||||
using T = typename std::remove_reference<Xs>::type::value_type;
|
||||
return std::array<T, sizeof...(i)>{{static_cast<Xs&&>(xs)[n + i]...}};
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr std::size_t len = std::tuple_size<
|
||||
typename std::remove_cv<
|
||||
typename std::remove_reference<Xs>::type
|
||||
>::type
|
||||
>::value;
|
||||
return drop_front_helper<n>(static_cast<Xs&&>(xs),
|
||||
std::make_index_sequence<(n < len ? len - n : 0)>{});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_empty_impl<ext::std::array_tag> {
|
||||
template <typename T, std::size_t N>
|
||||
static constexpr auto apply(std::array<T, N> const&) {
|
||||
return hana::bool_c<N == 0>;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Comparable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct equal_impl<ext::std::array_tag, ext::std::array_tag> {
|
||||
template <typename T, std::size_t n, typename U>
|
||||
static constexpr bool apply(std::array<T, n> const& xs, std::array<U, n> const& ys)
|
||||
{ return detail::equal(&xs[0], &xs[0] + n, &ys[0], &ys[0] + n); }
|
||||
|
||||
template <typename T, typename U>
|
||||
static constexpr auto apply(std::array<T, 0> const&, std::array<U, 0> const&)
|
||||
{ return hana::true_c; }
|
||||
|
||||
template <typename T, std::size_t n, typename U, std::size_t m>
|
||||
static constexpr auto apply(std::array<T, n> const&, std::array<U, m> const&)
|
||||
{ return hana::false_c; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Orderable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct less_impl<ext::std::array_tag, ext::std::array_tag> {
|
||||
template <typename T, 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) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_STD_ARRAY_HPP
|
@ -0,0 +1,140 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `std::integer_sequence` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP
|
||||
#define BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP
|
||||
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/fast_and.hpp>
|
||||
#include <boost/hana/ext/std/integral_constant.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
#include <boost/hana/fwd/equal.hpp>
|
||||
#include <boost/hana/fwd/is_empty.hpp>
|
||||
#include <boost/hana/fwd/unpack.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace std {
|
||||
//! @ingroup group-ext-std
|
||||
//! Adaptation of `std::integer_sequence` for Hana.
|
||||
//!
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! 1. `Comparable`\n
|
||||
//! Two `std::integer_sequence`s are equal if and only if they have the
|
||||
//! same number of elements, and if corresponding elements compare equal.
|
||||
//! The types of the elements held in both `integer_sequence`s may be
|
||||
//! different, as long as they can be compared.
|
||||
//! @include example/ext/std/integer_sequence/comparable.cpp
|
||||
//!
|
||||
//! 2. `Foldable`\n
|
||||
//! Folding an `integer_sequence` is equivalent to folding a sequence of
|
||||
//! `std::integral_constant`s with the corresponding types.
|
||||
//! @include example/ext/std/integer_sequence/foldable.cpp
|
||||
//!
|
||||
//! 3. `Iterable`\n
|
||||
//! Iterating over an `integer_sequence` is equivalent to iterating over
|
||||
//! a sequence of the corresponding `std::integral_constant`s.
|
||||
//! @include example/ext/std/integer_sequence/iterable.cpp
|
||||
//!
|
||||
//! 4. `Searchable`\n
|
||||
//! Searching through an `integer_sequence` is equivalent to searching
|
||||
//! through the corresponding sequence of `std::integral_constant`s.
|
||||
//! @include example/ext/std/integer_sequence/searchable.cpp
|
||||
template <typename T, T ...v>
|
||||
struct integer_sequence { };
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace std { struct integer_sequence_tag; }}
|
||||
|
||||
template <typename T, T ...v>
|
||||
struct tag_of<std::integer_sequence<T, v...>> {
|
||||
using type = ext::std::integer_sequence_tag;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Comparable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct equal_impl<ext::std::integer_sequence_tag, ext::std::integer_sequence_tag> {
|
||||
template <typename X, X ...xs, typename Y, Y ...ys>
|
||||
static constexpr hana::bool_<detail::fast_and<(xs == ys)...>::value>
|
||||
apply(std::integer_sequence<X, xs...> const&, std::integer_sequence<Y, ys...> const&)
|
||||
{ return {}; }
|
||||
|
||||
template <typename Xs, typename Ys>
|
||||
static constexpr hana::false_ apply(Xs const&, Ys const&, ...)
|
||||
{ return {}; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct unpack_impl<ext::std::integer_sequence_tag> {
|
||||
template <typename T, T ...v, typename F>
|
||||
static constexpr decltype(auto)
|
||||
apply(std::integer_sequence<T, v...> const&, F&& f) {
|
||||
return static_cast<F&&>(f)(std::integral_constant<T, v>{}...);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct at_impl<ext::std::integer_sequence_tag> {
|
||||
template <typename T, T ...v, typename N>
|
||||
static constexpr auto apply(std::integer_sequence<T, v...> const&, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr T values_[] = {v...};
|
||||
return std::integral_constant<T, values_[n]>{};
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct drop_front_impl<ext::std::integer_sequence_tag> {
|
||||
template <std::size_t n, typename T, T ...t, std::size_t ...i>
|
||||
static constexpr auto drop_front_helper(std::integer_sequence<T, t...>,
|
||||
std::index_sequence<i...>)
|
||||
{
|
||||
constexpr T ts[sizeof...(t)+1] = {t...}; // avoid 0-sized array
|
||||
return std::integer_sequence<T, ts[n + i]...>{};
|
||||
}
|
||||
|
||||
template <typename T, T ...t, typename N>
|
||||
static constexpr auto apply(std::integer_sequence<T, t...> ts, N const&) {
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr std::size_t len = sizeof...(t);
|
||||
return drop_front_helper<n>(ts,
|
||||
std::make_index_sequence<(n < len ? len - n : 0)>{});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_empty_impl<ext::std::integer_sequence_tag> {
|
||||
template <typename T, T ...xs>
|
||||
static constexpr auto apply(std::integer_sequence<T, xs...> const&)
|
||||
{ return hana::bool_c<sizeof...(xs) == 0>; }
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_STD_INTEGER_SEQUENCE_HPP
|
@ -0,0 +1,96 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `std::integral_constant` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP
|
||||
#define BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP
|
||||
|
||||
#include <boost/hana/concept/integral_constant.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/fwd/core/to.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/integral_constant.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace std {
|
||||
//! @ingroup group-ext-std
|
||||
//! Adapter for `std::integral_constant`s.
|
||||
//!
|
||||
//! Provided models
|
||||
//! ---------------
|
||||
//! 1. `Constant` and `IntegralConstant`\n
|
||||
//! A `std::integral_constant` is a model of the `IntegralConstant` and
|
||||
//! `Constant` concepts, just like `hana::integral_constant`s are. As a
|
||||
//! consequence, they are also implicitly a model of the concepts provided
|
||||
//! for all models of `Constant`.
|
||||
//! @include example/ext/std/integral_constant.cpp
|
||||
template <typename T, T v>
|
||||
struct integral_constant { };
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace std {
|
||||
template <typename T>
|
||||
struct integral_constant_tag { using value_type = T; };
|
||||
}}
|
||||
|
||||
namespace detail {
|
||||
template <typename T, T v>
|
||||
constexpr bool
|
||||
is_std_integral_constant(std::integral_constant<T, v>*)
|
||||
{ return true; }
|
||||
|
||||
constexpr bool is_std_integral_constant(...)
|
||||
{ return false; }
|
||||
|
||||
|
||||
template <typename T, T v>
|
||||
constexpr bool
|
||||
is_hana_integral_constant(hana::integral_constant<T, v>*)
|
||||
{ return true; }
|
||||
|
||||
constexpr bool is_hana_integral_constant(...)
|
||||
{ return false; }
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct tag_of<T, when<
|
||||
detail::is_std_integral_constant((T*)0) &&
|
||||
!detail::is_hana_integral_constant((T*)0)
|
||||
>> {
|
||||
using type = ext::std::integral_constant_tag<
|
||||
typename hana::tag_of<typename T::value_type>::type
|
||||
>;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Constant/IntegralConstant
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename T>
|
||||
struct IntegralConstant<ext::std::integral_constant_tag<T>> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
|
||||
template <typename T, typename C>
|
||||
struct to_impl<ext::std::integral_constant_tag<T>, C, when<
|
||||
hana::IntegralConstant<C>::value
|
||||
>> : embedding<is_embedded<typename C::value_type, T>::value> {
|
||||
template <typename N>
|
||||
static constexpr auto apply(N const&) {
|
||||
return std::integral_constant<T, N::value>{};
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_STD_INTEGRAL_CONSTANT_HPP
|
@ -0,0 +1,91 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `std::pair` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_STD_PAIR_HPP
|
||||
#define BOOST_HANA_EXT_STD_PAIR_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/fwd/core/make.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/first.hpp>
|
||||
#include <boost/hana/fwd/second.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace std {
|
||||
//! @ingroup group-ext-std
|
||||
//! Adaptation of `std::pair` for Hana.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! A `std::pair` models exactly the same concepts as a `hana::pair`.
|
||||
//! Please refer to the documentation of `hana::pair` for details.
|
||||
//!
|
||||
//! @include example/ext/std/pair.cpp
|
||||
template <typename First, typename Second>
|
||||
struct pair { };
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace std { struct pair_tag; }}
|
||||
|
||||
template <typename First, typename Second>
|
||||
struct tag_of<std::pair<First, Second>> {
|
||||
using type = ext::std::pair_tag;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Product
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct make_impl<ext::std::pair_tag> {
|
||||
template <typename X, typename Y>
|
||||
static constexpr decltype(auto) apply(X&& x, Y&& y) {
|
||||
return std::make_pair(static_cast<X&&>(x),
|
||||
static_cast<Y&&>(y));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct first_impl<ext::std::pair_tag> {
|
||||
template <typename T, typename U>
|
||||
static constexpr T const& apply(std::pair<T, U> const& p)
|
||||
{ return p.first; }
|
||||
|
||||
template <typename T, typename U>
|
||||
static constexpr T& apply(std::pair<T, U>& p)
|
||||
{ return p.first; }
|
||||
|
||||
template <typename T, typename U>
|
||||
static constexpr T&& apply(std::pair<T, U>&& p)
|
||||
{ return static_cast<T&&>(p.first); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct second_impl<ext::std::pair_tag> {
|
||||
template <typename T, typename U>
|
||||
static constexpr U const& apply(std::pair<T, U> const& p)
|
||||
{ return p.second; }
|
||||
|
||||
template <typename T, typename U>
|
||||
static constexpr U& apply(std::pair<T, U>& p)
|
||||
{ return p.second; }
|
||||
|
||||
template <typename T, typename U>
|
||||
static constexpr U&& apply(std::pair<T, U>&& p)
|
||||
{ return static_cast<U&&>(p.second); }
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_STD_PAIR_HPP
|
164
_deps/boost-src/libs/hana/include/boost/hana/ext/std/ratio.hpp
Normal file
164
_deps/boost-src/libs/hana/include/boost/hana/ext/std/ratio.hpp
Normal file
@ -0,0 +1,164 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `std::ratio` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_STD_RATIO_HPP
|
||||
#define BOOST_HANA_EXT_STD_RATIO_HPP
|
||||
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/concept/integral_constant.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/fwd/core/to.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/div.hpp>
|
||||
#include <boost/hana/fwd/equal.hpp>
|
||||
#include <boost/hana/fwd/less.hpp>
|
||||
#include <boost/hana/fwd/minus.hpp>
|
||||
#include <boost/hana/fwd/mod.hpp>
|
||||
#include <boost/hana/fwd/mult.hpp>
|
||||
#include <boost/hana/fwd/one.hpp>
|
||||
#include <boost/hana/fwd/plus.hpp>
|
||||
#include <boost/hana/fwd/zero.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <ratio>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace std {
|
||||
//! @ingroup group-ext-std
|
||||
//! Adaptation of `std::ratio` for Hana.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! 1. `Comparable`\n
|
||||
//! `std::ratio`s are compared for equality using `std::ratio_equal`.
|
||||
//! @include example/ext/std/ratio/comparable.cpp
|
||||
//!
|
||||
//! 2. `Orderable`\n
|
||||
//! `std::ratio`s are ordered using `std::ratio_less`.
|
||||
//! @include example/ext/std/ratio/orderable.cpp
|
||||
//!
|
||||
//! 3. `Monoid`, `Group`, `Ring`, and `EuclideanRing`\n
|
||||
//! `std::ratio`s are added, subtracted, multiplied and divided using
|
||||
//! `std::ratio_add`, `std::ratio_subtract`, `std::ratio_multiply` and
|
||||
//! `std::ratio_divide`, respectively. Furthermore, the neutral element
|
||||
//! for the additive operation is `std::ratio<0, 1>{}`, and the neutral
|
||||
//! element for the multiplicative operation is `std::ratio<1, 1>{}`.
|
||||
//! @include example/ext/std/ratio/arithmetic.cpp
|
||||
template <std::intmax_t Num, std::intmax_t Denom>
|
||||
class ratio { };
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace std { struct ratio_tag; }}
|
||||
|
||||
template <std::intmax_t num, std::intmax_t den>
|
||||
struct tag_of<std::ratio<num, den>> {
|
||||
using type = ext::std::ratio_tag;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Conversion from IntegralConstants
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <typename C>
|
||||
struct to_impl<ext::std::ratio_tag, C, when<
|
||||
hana::IntegralConstant<C>::value
|
||||
>> {
|
||||
template <typename N>
|
||||
static constexpr auto apply(N const&) {
|
||||
return std::ratio<N::value>{};
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Comparable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct equal_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
|
||||
template <typename R1, typename R2>
|
||||
static constexpr auto apply(R1 const&, R2 const&)
|
||||
{ return hana::bool_c<std::ratio_equal<R1, R2>::value>; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Orderable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct less_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
|
||||
template <typename R1, typename R2>
|
||||
static constexpr auto apply(R1 const&, R2 const&)
|
||||
{ return hana::bool_c<std::ratio_less<R1, R2>::value>; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Monoid
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct plus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
|
||||
template <typename R1, typename R2>
|
||||
static constexpr std::ratio_add<R1, R2> apply(R1 const&, R2 const&)
|
||||
{ return {}; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct zero_impl<ext::std::ratio_tag> {
|
||||
static constexpr std::ratio<0> apply()
|
||||
{ return {}; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Group
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct minus_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
|
||||
template <typename R1, typename R2>
|
||||
static constexpr std::ratio_subtract<R1, R2> apply(R1 const&, R2 const&)
|
||||
{ return {}; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Ring
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct mult_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
|
||||
template <typename R1, typename R2>
|
||||
static constexpr std::ratio_multiply<R1, R2> apply(R1 const&, R2 const&)
|
||||
{ return {}; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct one_impl<ext::std::ratio_tag> {
|
||||
static constexpr std::ratio<1> apply()
|
||||
{ return {}; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// EuclideanRing
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct div_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
|
||||
template <typename R1, typename R2>
|
||||
static constexpr std::ratio_divide<R1, R2> apply(R1 const&, R2 const&)
|
||||
{ return {}; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct mod_impl<ext::std::ratio_tag, ext::std::ratio_tag> {
|
||||
template <typename R1, typename R2>
|
||||
static constexpr std::ratio<0> apply(R1 const&, R2 const&)
|
||||
{ return {}; }
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_STD_RATIO_HPP
|
180
_deps/boost-src/libs/hana/include/boost/hana/ext/std/tuple.hpp
Normal file
180
_deps/boost-src/libs/hana/include/boost/hana/ext/std/tuple.hpp
Normal file
@ -0,0 +1,180 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `std::tuple` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_STD_TUPLE_HPP
|
||||
#define BOOST_HANA_EXT_STD_TUPLE_HPP
|
||||
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
#include <boost/hana/fwd/at.hpp>
|
||||
#include <boost/hana/fwd/core/make.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/fwd/drop_front.hpp>
|
||||
#include <boost/hana/fwd/empty.hpp>
|
||||
#include <boost/hana/fwd/flatten.hpp>
|
||||
#include <boost/hana/fwd/front.hpp>
|
||||
#include <boost/hana/fwd/is_empty.hpp>
|
||||
#include <boost/hana/fwd/length.hpp>
|
||||
#include <boost/hana/fwd/lift.hpp>
|
||||
#include <boost/hana/integral_constant.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
namespace std {
|
||||
//! @ingroup group-ext-std
|
||||
//! Adapter for `std::tuple`s.
|
||||
//!
|
||||
//!
|
||||
//! Modeled concepts
|
||||
//! ----------------
|
||||
//! A `std::tuple` is a model of the `Sequence` concept, and all the
|
||||
//! concepts it refines. That makes it essentially the same as a Hana
|
||||
//! tuple, although the complexity of some operations might differ from
|
||||
//! that of Hana's tuple.
|
||||
//!
|
||||
//! @include example/ext/std/tuple.cpp
|
||||
template <typename ...T>
|
||||
struct tuple { };
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace std { struct tuple_tag; }}
|
||||
|
||||
template <typename ...Xs>
|
||||
struct tag_of<std::tuple<Xs...>> {
|
||||
using type = ext::std::tuple_tag;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// make
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct make_impl<ext::std::tuple_tag> {
|
||||
template <typename ...Xs>
|
||||
static constexpr decltype(auto) apply(Xs&& ...xs) {
|
||||
return std::make_tuple(static_cast<Xs&&>(xs)...);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Applicative
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct lift_impl<ext::std::tuple_tag> {
|
||||
template <typename X>
|
||||
static constexpr auto apply(X&& x) {
|
||||
return std::tuple<typename detail::decay<X>::type>{
|
||||
static_cast<X&&>(x)};
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Monad
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct flatten_impl<ext::std::tuple_tag> {
|
||||
template <typename Xs, std::size_t ...i>
|
||||
static constexpr decltype(auto)
|
||||
flatten_helper(Xs&& xs, std::index_sequence<i...>) {
|
||||
return std::tuple_cat(std::get<i>(static_cast<Xs&&>(xs))...);
|
||||
}
|
||||
|
||||
template <typename Xs>
|
||||
static constexpr decltype(auto) apply(Xs&& xs) {
|
||||
using Raw = typename std::remove_reference<Xs>::type;
|
||||
constexpr std::size_t Length = std::tuple_size<Raw>::value;
|
||||
return flatten_helper(static_cast<Xs&&>(xs),
|
||||
std::make_index_sequence<Length>{});
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// MonadPlus
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct empty_impl<ext::std::tuple_tag> {
|
||||
static constexpr auto apply()
|
||||
{ return std::tuple<>{}; }
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Iterable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct front_impl<ext::std::tuple_tag> {
|
||||
template <typename Xs>
|
||||
static constexpr decltype(auto) apply(Xs&& xs) {
|
||||
return std::get<0>(static_cast<Xs&&>(xs));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct drop_front_impl<ext::std::tuple_tag> {
|
||||
template <std::size_t n, typename Xs, std::size_t ...i>
|
||||
static constexpr auto drop_front_helper(Xs&& xs, std::index_sequence<i...>) {
|
||||
return std::make_tuple(
|
||||
hana::at_c<n + i>(static_cast<Xs&&>(xs))...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Xs, typename N>
|
||||
static constexpr auto apply(Xs&& xs, N const&) {
|
||||
using Raw = typename std::remove_reference<Xs>::type;
|
||||
constexpr std::size_t n = N::value;
|
||||
constexpr auto len = std::tuple_size<Raw>::value;
|
||||
return drop_front_helper<n>(static_cast<Xs&&>(xs),
|
||||
std::make_index_sequence<(n < len ? len - n : 0)>{});
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct is_empty_impl<ext::std::tuple_tag> {
|
||||
template <typename ...Xs>
|
||||
static constexpr auto apply(std::tuple<Xs...> const&)
|
||||
{ return hana::bool_c<sizeof...(Xs) == 0>; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct at_impl<ext::std::tuple_tag> {
|
||||
template <typename Xs, typename N>
|
||||
static constexpr decltype(auto) apply(Xs&& xs, N const&) {
|
||||
constexpr std::size_t index = N::value;
|
||||
return std::get<index>(static_cast<Xs&&>(xs));
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Foldable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct length_impl<ext::std::tuple_tag> {
|
||||
template <typename ...Xs>
|
||||
static constexpr auto apply(std::tuple<Xs...> const&) {
|
||||
return hana::size_c<sizeof...(Xs)>;
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Sequence
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct Sequence<ext::std::tuple_tag> {
|
||||
static constexpr bool value = true;
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_STD_TUPLE_HPP
|
110
_deps/boost-src/libs/hana/include/boost/hana/ext/std/vector.hpp
Normal file
110
_deps/boost-src/libs/hana/include/boost/hana/ext/std/vector.hpp
Normal file
@ -0,0 +1,110 @@
|
||||
/*!
|
||||
@file
|
||||
Adapts `std::vector` for use with Hana.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
Copyright Gonzalo Brito Gadeschi 2015
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_EXT_STD_VECTOR_HPP
|
||||
#define BOOST_HANA_EXT_STD_VECTOR_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/equal.hpp>
|
||||
#include <boost/hana/fwd/core/tag_of.hpp>
|
||||
#include <boost/hana/less.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace ext { namespace std { struct vector_tag; }}
|
||||
|
||||
template <typename T, typename Allocator>
|
||||
struct tag_of<std::vector<T, Allocator>> {
|
||||
using type = ext::std::vector_tag;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Comparable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct equal_impl<ext::std::vector_tag, ext::std::vector_tag> {
|
||||
template <typename T1, typename A1, typename T2, typename A2>
|
||||
static bool apply(std::vector<T1, A1> const& v1,
|
||||
std::vector<T2, A2> const& v2)
|
||||
{
|
||||
return std::equal(begin(v1), end(v1),
|
||||
begin(v2), end(v2),
|
||||
hana::equal);
|
||||
}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Orderable
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct less_impl<ext::std::vector_tag, ext::std::vector_tag> {
|
||||
template <typename T1, typename A1, typename T2, typename A2>
|
||||
static bool apply(std::vector<T1, A1> const& v1,
|
||||
std::vector<T2, A2> const& v2)
|
||||
{
|
||||
return std::lexicographical_compare(begin(v1), end(v1),
|
||||
begin(v2), end(v2),
|
||||
hana::less);
|
||||
}
|
||||
};
|
||||
|
||||
#if 0
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Functor
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
template <>
|
||||
struct transform_impl<ext::std::vector_tag> {
|
||||
template <typename V, typename F>
|
||||
static auto apply(V&& v, F&& f) {
|
||||
using U = std::remove_cv_t<std::remove_reference_t<
|
||||
decltype(f(*v.begin()))
|
||||
>>;
|
||||
using Alloc = typename std::remove_reference_t<V>::allocator_type;
|
||||
using NewAlloc = typename std::allocator_traits<Alloc>::
|
||||
template rebind_alloc<U>;
|
||||
std::vector<U, NewAlloc> result; result.reserve(v.size());
|
||||
|
||||
std::transform(begin(v), end(v),
|
||||
std::back_inserter(result), std::forward<F>(f));
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T, typename Alloc, typename F>
|
||||
static auto apply(std::vector<T, Alloc>&& v, F&& f)
|
||||
-> std::enable_if_t<
|
||||
std::is_same<
|
||||
T,
|
||||
std::remove_cv_t<std::remove_reference_t<
|
||||
decltype(f(*v.begin()))
|
||||
>>
|
||||
>{}
|
||||
, std::vector<T, Alloc>
|
||||
>
|
||||
{
|
||||
// If we receive a rvalue and the function returns elements of
|
||||
// the same type, we modify the vector in-place instead of
|
||||
// returning a new one.
|
||||
std::transform(std::make_move_iterator(begin(v)),
|
||||
std::make_move_iterator(end(v)),
|
||||
begin(v), std::forward<F>(f));
|
||||
return std::move(v);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXT_STD_VECTOR_HPP
|
50
_deps/boost-src/libs/hana/include/boost/hana/extend.hpp
Normal file
50
_deps/boost-src/libs/hana/include/boost/hana/extend.hpp
Normal file
@ -0,0 +1,50 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::extend`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_EXTEND_HPP
|
||||
#define BOOST_HANA_EXTEND_HPP
|
||||
|
||||
#include <boost/hana/fwd/extend.hpp>
|
||||
|
||||
#include <boost/hana/concept/comonad.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/duplicate.hpp>
|
||||
#include <boost/hana/transform.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename W_, typename F>
|
||||
constexpr decltype(auto) extend_t::operator()(W_&& w, F&& f) const {
|
||||
using W = typename hana::tag_of<W_>::type;
|
||||
using Extend = BOOST_HANA_DISPATCH_IF(extend_impl<W>,
|
||||
hana::Comonad<W>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Comonad<W>::value,
|
||||
"hana::extend(w, f) requires 'w' to be a Comonad");
|
||||
#endif
|
||||
|
||||
return Extend::apply(static_cast<W_&&>(w), static_cast<F&&>(f));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename W, bool condition>
|
||||
struct extend_impl<W, when<condition>> : default_ {
|
||||
template <typename X, typename F>
|
||||
static constexpr decltype(auto) apply(X&& x, F&& f) {
|
||||
return hana::transform(hana::duplicate(static_cast<X&&>(x)),
|
||||
static_cast<F&&>(f));
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXTEND_HPP
|
45
_deps/boost-src/libs/hana/include/boost/hana/extract.hpp
Normal file
45
_deps/boost-src/libs/hana/include/boost/hana/extract.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::extract`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_EXTRACT_HPP
|
||||
#define BOOST_HANA_EXTRACT_HPP
|
||||
|
||||
#include <boost/hana/fwd/extract.hpp>
|
||||
|
||||
#include <boost/hana/concept/comonad.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename W_>
|
||||
constexpr decltype(auto) extract_t::operator()(W_&& w) const {
|
||||
using W = typename hana::tag_of<W_>::type;
|
||||
using Extract = BOOST_HANA_DISPATCH_IF(extract_impl<W>,
|
||||
hana::Comonad<W>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Comonad<W>::value,
|
||||
"hana::extract(w) requires 'w' to be a Comonad");
|
||||
#endif
|
||||
|
||||
return Extract::apply(static_cast<W_&&>(w));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename W, bool condition>
|
||||
struct extract_impl<W, when<condition>> : default_ {
|
||||
template <typename ...Args>
|
||||
static constexpr auto apply(Args&& ...args) = delete;
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_EXTRACT_HPP
|
74
_deps/boost-src/libs/hana/include/boost/hana/fill.hpp
Normal file
74
_deps/boost-src/libs/hana/include/boost/hana/fill.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::fill`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FILL_HPP
|
||||
#define BOOST_HANA_FILL_HPP
|
||||
|
||||
#include <boost/hana/fwd/fill.hpp>
|
||||
|
||||
#include <boost/hana/concept/functor.hpp>
|
||||
#include <boost/hana/concept/sequence.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/core/make.hpp>
|
||||
#include <boost/hana/functional/always.hpp>
|
||||
#include <boost/hana/transform.hpp>
|
||||
#include <boost/hana/unpack.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename Value>
|
||||
constexpr auto fill_t::operator()(Xs&& xs, Value&& value) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using Fill = BOOST_HANA_DISPATCH_IF(fill_impl<S>,
|
||||
hana::Functor<S>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Functor<S>::value,
|
||||
"hana::fill(xs, value) requires 'xs' to be a Functor");
|
||||
#endif
|
||||
|
||||
return Fill::apply(static_cast<Xs&&>(xs),
|
||||
static_cast<Value&&>(value));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename Fun, bool condition>
|
||||
struct fill_impl<Fun, when<condition>> : default_ {
|
||||
template <typename Xs, typename Value>
|
||||
static constexpr auto apply(Xs&& xs, Value&& v) {
|
||||
return hana::transform(static_cast<Xs&&>(xs),
|
||||
hana::always(static_cast<Value&&>(v))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct fill_impl<S, when<Sequence<S>::value>> {
|
||||
//! @cond
|
||||
template <typename V>
|
||||
struct filler {
|
||||
V const& v;
|
||||
template <typename ...Xs>
|
||||
constexpr auto operator()(Xs const& ...xs) const {
|
||||
return hana::make<S>(((void)xs, v)...);
|
||||
}
|
||||
};
|
||||
//! @endcond
|
||||
|
||||
template <typename Xs, typename V>
|
||||
static constexpr auto apply(Xs const& xs, V const& v) {
|
||||
return hana::unpack(xs, filler<V>{v});
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FILL_HPP
|
135
_deps/boost-src/libs/hana/include/boost/hana/filter.hpp
Normal file
135
_deps/boost-src/libs/hana/include/boost/hana/filter.hpp
Normal file
@ -0,0 +1,135 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::filter`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FILTER_HPP
|
||||
#define BOOST_HANA_FILTER_HPP
|
||||
|
||||
#include <boost/hana/fwd/filter.hpp>
|
||||
|
||||
#include <boost/hana/at.hpp>
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/chain.hpp>
|
||||
#include <boost/hana/concept/monad_plus.hpp>
|
||||
#include <boost/hana/concept/sequence.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/core/make.hpp>
|
||||
#include <boost/hana/detail/algorithm.hpp>
|
||||
#include <boost/hana/detail/array.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
#include <boost/hana/empty.hpp>
|
||||
#include <boost/hana/lift.hpp>
|
||||
#include <boost/hana/unpack.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename Pred>
|
||||
constexpr auto filter_t::operator()(Xs&& xs, Pred&& pred) const {
|
||||
using M = typename hana::tag_of<Xs>::type;
|
||||
using Filter = BOOST_HANA_DISPATCH_IF(filter_impl<M>,
|
||||
hana::MonadPlus<M>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::MonadPlus<M>::value,
|
||||
"hana::filter(xs, pred) requires 'xs' to be a MonadPlus");
|
||||
#endif
|
||||
|
||||
return Filter::apply(static_cast<Xs&&>(xs),
|
||||
static_cast<Pred&&>(pred));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
namespace detail {
|
||||
template <typename Pred, typename M>
|
||||
struct lift_or_empty {
|
||||
template <typename X>
|
||||
static constexpr auto helper(X&& x, hana::true_)
|
||||
{ return hana::lift<M>(static_cast<X&&>(x)); }
|
||||
|
||||
template <typename X>
|
||||
static constexpr auto helper(X&&, hana::false_)
|
||||
{ return hana::empty<M>(); }
|
||||
|
||||
template <typename X>
|
||||
constexpr auto operator()(X&& x) const {
|
||||
constexpr bool cond = decltype(std::declval<Pred>()(x))::value;
|
||||
return helper(static_cast<X&&>(x), hana::bool_c<cond>);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename M, bool condition>
|
||||
struct filter_impl<M, when<condition>> : default_ {
|
||||
template <typename Xs, typename Pred>
|
||||
static constexpr decltype(auto) apply(Xs&& xs, Pred const&) {
|
||||
return hana::chain(static_cast<Xs&&>(xs),
|
||||
detail::lift_or_empty<Pred, M>{}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <bool ...b>
|
||||
struct filter_indices {
|
||||
static constexpr auto compute_indices() {
|
||||
constexpr bool bs[] = {b..., false}; // avoid empty array
|
||||
constexpr std::size_t N = detail::count(bs, bs + sizeof(bs), true);
|
||||
detail::array<std::size_t, N> indices{};
|
||||
std::size_t* keep = &indices[0];
|
||||
for (std::size_t i = 0; i < sizeof...(b); ++i)
|
||||
if (bs[i])
|
||||
*keep++ = i;
|
||||
return indices;
|
||||
}
|
||||
|
||||
static constexpr auto cached_indices = compute_indices();
|
||||
};
|
||||
|
||||
template <typename Pred>
|
||||
struct make_filter_indices {
|
||||
Pred const& pred;
|
||||
template <typename ...X>
|
||||
auto operator()(X&& ...x) const -> filter_indices<
|
||||
static_cast<bool>(detail::decay<
|
||||
decltype(pred(static_cast<X&&>(x)))
|
||||
>::type::value)...
|
||||
> { return {}; }
|
||||
};
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
struct filter_impl<S, when<Sequence<S>::value>> {
|
||||
template <typename Indices, typename Xs, std::size_t ...i>
|
||||
static constexpr auto filter_helper(Xs&& xs, std::index_sequence<i...>) {
|
||||
return hana::make<S>(
|
||||
hana::at_c<Indices::cached_indices[i]>(static_cast<Xs&&>(xs))...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename Xs, typename Pred>
|
||||
static constexpr auto apply(Xs&& xs, Pred const& pred) {
|
||||
using Indices = decltype(
|
||||
hana::unpack(static_cast<Xs&&>(xs),
|
||||
detail::make_filter_indices<Pred>{pred})
|
||||
);
|
||||
|
||||
return filter_impl::filter_helper<Indices>(
|
||||
static_cast<Xs&&>(xs),
|
||||
std::make_index_sequence<Indices::cached_indices.size()>{}
|
||||
);
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FILTER_HPP
|
61
_deps/boost-src/libs/hana/include/boost/hana/find.hpp
Normal file
61
_deps/boost-src/libs/hana/include/boost/hana/find.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::find`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FIND_HPP
|
||||
#define BOOST_HANA_FIND_HPP
|
||||
|
||||
#include <boost/hana/fwd/find.hpp>
|
||||
|
||||
#include <boost/hana/concept/searchable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/equal.hpp>
|
||||
#include <boost/hana/find_if.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename Key>
|
||||
constexpr auto find_t::operator()(Xs&& xs, Key const& key) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using Find = BOOST_HANA_DISPATCH_IF(find_impl<S>,
|
||||
hana::Searchable<S>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Searchable<S>::value,
|
||||
"hana::find(xs, key) requires 'xs' to be Searchable");
|
||||
#endif
|
||||
|
||||
return Find::apply(static_cast<Xs&&>(xs), key);
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
namespace detail {
|
||||
template <typename T>
|
||||
struct equal_to {
|
||||
T const& t;
|
||||
template <typename U>
|
||||
constexpr auto operator()(U const& u) const {
|
||||
return hana::equal(t, u);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename S, bool condition>
|
||||
struct find_impl<S, when<condition>> : default_ {
|
||||
template <typename Xs, typename Key>
|
||||
static constexpr auto apply(Xs&& xs, Key const& key) {
|
||||
return hana::find_if(static_cast<Xs&&>(xs),
|
||||
detail::equal_to<Key>{key});
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FIND_HPP
|
129
_deps/boost-src/libs/hana/include/boost/hana/find_if.hpp
Normal file
129
_deps/boost-src/libs/hana/include/boost/hana/find_if.hpp
Normal file
@ -0,0 +1,129 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::find_if`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FIND_IF_HPP
|
||||
#define BOOST_HANA_FIND_IF_HPP
|
||||
|
||||
#include <boost/hana/fwd/find_if.hpp>
|
||||
|
||||
#include <boost/hana/accessors.hpp>
|
||||
#include <boost/hana/at.hpp>
|
||||
#include <boost/hana/bool.hpp>
|
||||
#include <boost/hana/concept/iterable.hpp>
|
||||
#include <boost/hana/concept/searchable.hpp>
|
||||
#include <boost/hana/concept/struct.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/first.hpp>
|
||||
#include <boost/hana/functional/compose.hpp>
|
||||
#include <boost/hana/index_if.hpp>
|
||||
#include <boost/hana/second.hpp>
|
||||
#include <boost/hana/transform.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename Pred>
|
||||
constexpr auto find_if_t::operator()(Xs&& xs, Pred&& pred) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using FindIf = BOOST_HANA_DISPATCH_IF(find_if_impl<S>,
|
||||
hana::Searchable<S>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Searchable<S>::value,
|
||||
"hana::find_if(xs, pred) requires 'xs' to be a Searchable");
|
||||
#endif
|
||||
|
||||
return FindIf::apply(static_cast<Xs&&>(xs), static_cast<Pred&&>(pred));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename S, bool condition>
|
||||
struct find_if_impl<S, when<condition>> : default_ {
|
||||
template <typename ...Args>
|
||||
static constexpr auto apply(Args&& ...) = delete;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
template <typename Xs>
|
||||
struct partial_at {
|
||||
Xs const& xs;
|
||||
|
||||
template <typename I>
|
||||
constexpr decltype(auto) operator()(I i) const {
|
||||
return hana::at(xs, i);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
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) {
|
||||
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)});
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct find_if_impl<T[N]> {
|
||||
template <typename Xs>
|
||||
static constexpr auto find_if_helper(Xs&&, hana::false_)
|
||||
{ return hana::nothing; }
|
||||
|
||||
template <typename Xs>
|
||||
static constexpr auto find_if_helper(Xs&& xs, hana::true_)
|
||||
{ return hana::just(static_cast<Xs&&>(xs)[0]); }
|
||||
|
||||
template <typename Xs, typename Pred>
|
||||
static constexpr auto apply(Xs&& xs, Pred&& pred) {
|
||||
return find_if_helper(static_cast<Xs&&>(xs),
|
||||
hana::bool_c<decltype(
|
||||
static_cast<Pred&&>(pred)(static_cast<Xs&&>(xs)[0])
|
||||
)::value>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
namespace struct_detail {
|
||||
template <typename X>
|
||||
struct get_member {
|
||||
X x;
|
||||
template <typename Member>
|
||||
constexpr decltype(auto) operator()(Member&& member) && {
|
||||
return hana::second(static_cast<Member&&>(member))(
|
||||
static_cast<X&&>(x)
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename S>
|
||||
struct find_if_impl<S, when<hana::Struct<S>::value>> {
|
||||
template <typename X, typename Pred>
|
||||
static constexpr decltype(auto) apply(X&& x, Pred&& pred) {
|
||||
return hana::transform(
|
||||
hana::find_if(hana::accessors<S>(),
|
||||
hana::compose(static_cast<Pred&&>(pred), hana::first)
|
||||
),
|
||||
struct_detail::get_member<X>{static_cast<X&&>(x)}
|
||||
);
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FIND_IF_HPP
|
45
_deps/boost-src/libs/hana/include/boost/hana/first.hpp
Normal file
45
_deps/boost-src/libs/hana/include/boost/hana/first.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::first`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FIRST_HPP
|
||||
#define BOOST_HANA_FIRST_HPP
|
||||
|
||||
#include <boost/hana/fwd/first.hpp>
|
||||
|
||||
#include <boost/hana/concept/product.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Pair>
|
||||
constexpr decltype(auto) first_t::operator()(Pair&& pair) const {
|
||||
using P = typename hana::tag_of<Pair>::type;
|
||||
using First = BOOST_HANA_DISPATCH_IF(first_impl<P>,
|
||||
hana::Product<P>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Product<P>::value,
|
||||
"hana::first(pair) requires 'pair' to be a Product");
|
||||
#endif
|
||||
|
||||
return First::apply(static_cast<Pair&&>(pair));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename P, bool condition>
|
||||
struct first_impl<P, when<condition>> : default_ {
|
||||
template <typename ...Args>
|
||||
static constexpr auto apply(Args&& ...) = delete;
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FIRST_HPP
|
62
_deps/boost-src/libs/hana/include/boost/hana/flatten.hpp
Normal file
62
_deps/boost-src/libs/hana/include/boost/hana/flatten.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::flatten`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FLATTEN_HPP
|
||||
#define BOOST_HANA_FLATTEN_HPP
|
||||
|
||||
#include <boost/hana/fwd/flatten.hpp>
|
||||
|
||||
#include <boost/hana/concept/monad.hpp>
|
||||
#include <boost/hana/concept/sequence.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/core/make.hpp>
|
||||
#include <boost/hana/detail/unpack_flatten.hpp>
|
||||
#include <boost/hana/functional/id.hpp>
|
||||
#include <boost/hana/fwd/chain.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs>
|
||||
constexpr auto flatten_t::operator()(Xs&& xs) const {
|
||||
using M = typename hana::tag_of<Xs>::type;
|
||||
using Flatten = BOOST_HANA_DISPATCH_IF(flatten_impl<M>,
|
||||
hana::Monad<M>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Monad<M>::value,
|
||||
"hana::flatten(xs) requires 'xs' to be a Monad");
|
||||
#endif
|
||||
|
||||
return Flatten::apply(static_cast<Xs&&>(xs));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename M, bool condition>
|
||||
struct flatten_impl<M, when<condition>> : default_ {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs&& xs)
|
||||
{ return hana::chain(static_cast<Xs&&>(xs), hana::id); }
|
||||
};
|
||||
|
||||
template <typename S>
|
||||
struct flatten_impl<S, when<Sequence<S>::value>> {
|
||||
template <typename Xs>
|
||||
static constexpr auto apply(Xs&& xs) {
|
||||
return detail::unpack_flatten(static_cast<Xs&&>(xs), hana::make<S>);
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FLATTEN_HPP
|
17
_deps/boost-src/libs/hana/include/boost/hana/fold.hpp
Normal file
17
_deps/boost-src/libs/hana/include/boost/hana/fold.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::fold`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FOLD_HPP
|
||||
#define BOOST_HANA_FOLD_HPP
|
||||
|
||||
#include <boost/hana/fwd/fold.hpp>
|
||||
|
||||
#include <boost/hana/fold_left.hpp>
|
||||
|
||||
#endif // !BOOST_HANA_FOLD_HPP
|
97
_deps/boost-src/libs/hana/include/boost/hana/fold_left.hpp
Normal file
97
_deps/boost-src/libs/hana/include/boost/hana/fold_left.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::fold_left`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FOLD_LEFT_HPP
|
||||
#define BOOST_HANA_FOLD_LEFT_HPP
|
||||
|
||||
#include <boost/hana/fwd/fold_left.hpp>
|
||||
|
||||
#include <boost/hana/concept/foldable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/detail/variadic/foldl1.hpp>
|
||||
#include <boost/hana/functional/partial.hpp>
|
||||
#include <boost/hana/unpack.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename State, typename F>
|
||||
constexpr decltype(auto) fold_left_t::operator()(Xs&& xs, State&& state, F&& f) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using FoldLeft = BOOST_HANA_DISPATCH_IF(fold_left_impl<S>,
|
||||
hana::Foldable<S>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Foldable<S>::value,
|
||||
"hana::fold_left(xs, state, f) requires 'xs' to be Foldable");
|
||||
#endif
|
||||
|
||||
return FoldLeft::apply(static_cast<Xs&&>(xs),
|
||||
static_cast<State&&>(state),
|
||||
static_cast<F&&>(f));
|
||||
}
|
||||
|
||||
template <typename Xs, typename F>
|
||||
constexpr decltype(auto) fold_left_t::operator()(Xs&& xs, F&& f) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using FoldLeft = BOOST_HANA_DISPATCH_IF(fold_left_impl<S>,
|
||||
hana::Foldable<S>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Foldable<S>::value,
|
||||
"hana::fold_left(xs, f) requires 'xs' to be Foldable");
|
||||
#endif
|
||||
|
||||
return FoldLeft::apply(static_cast<Xs&&>(xs), static_cast<F&&>(f));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
namespace detail {
|
||||
template <typename F, typename State>
|
||||
struct variadic_foldl1 {
|
||||
F& f;
|
||||
State& state;
|
||||
template <typename ...T>
|
||||
constexpr decltype(auto) operator()(T&& ...t) const {
|
||||
return detail::variadic::foldl1(
|
||||
static_cast<F&&>(f),
|
||||
static_cast<State&&>(state),
|
||||
static_cast<T&&>(t)...
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T, bool condition>
|
||||
struct fold_left_impl<T, when<condition>> : default_ {
|
||||
// with state
|
||||
template <typename Xs, typename S, typename F>
|
||||
static constexpr decltype(auto) apply(Xs&& xs, S&& s, F&& f) {
|
||||
return hana::unpack(static_cast<Xs&&>(xs),
|
||||
detail::variadic_foldl1<F, S>{f, s}
|
||||
);
|
||||
}
|
||||
|
||||
// without state
|
||||
template <typename Xs, typename F>
|
||||
static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
|
||||
return hana::unpack(static_cast<Xs&&>(xs),
|
||||
hana::partial(
|
||||
detail::variadic::foldl1,
|
||||
static_cast<F&&>(f)
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FOLD_LEFT_HPP
|
97
_deps/boost-src/libs/hana/include/boost/hana/fold_right.hpp
Normal file
97
_deps/boost-src/libs/hana/include/boost/hana/fold_right.hpp
Normal file
@ -0,0 +1,97 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::fold_right`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FOLD_RIGHT_HPP
|
||||
#define BOOST_HANA_FOLD_RIGHT_HPP
|
||||
|
||||
#include <boost/hana/fwd/fold_right.hpp>
|
||||
|
||||
#include <boost/hana/concept/foldable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/detail/variadic/foldr1.hpp>
|
||||
#include <boost/hana/functional/partial.hpp>
|
||||
#include <boost/hana/fwd/unpack.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename State, typename F>
|
||||
constexpr decltype(auto) fold_right_t::operator()(Xs&& xs, State&& state, F&& f) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using FoldRight = BOOST_HANA_DISPATCH_IF(fold_right_impl<S>,
|
||||
hana::Foldable<S>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Foldable<S>::value,
|
||||
"hana::fold_right(xs, state, f) requires 'xs' to be Foldable");
|
||||
#endif
|
||||
|
||||
return FoldRight::apply(static_cast<Xs&&>(xs),
|
||||
static_cast<State&&>(state),
|
||||
static_cast<F&&>(f));
|
||||
}
|
||||
|
||||
template <typename Xs, typename F>
|
||||
constexpr decltype(auto) fold_right_t::operator()(Xs&& xs, F&& f) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using FoldRight = BOOST_HANA_DISPATCH_IF(fold_right_impl<S>,
|
||||
hana::Foldable<S>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Foldable<S>::value,
|
||||
"hana::fold_right(xs, f) requires 'xs' to be Foldable");
|
||||
#endif
|
||||
|
||||
return FoldRight::apply(static_cast<Xs&&>(xs), static_cast<F&&>(f));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
namespace detail {
|
||||
template <typename F, typename State>
|
||||
struct variadic_foldr {
|
||||
F& f;
|
||||
State& state;
|
||||
template <typename ...T>
|
||||
constexpr decltype(auto) operator()(T&& ...t) const {
|
||||
return detail::variadic::foldr(
|
||||
static_cast<F&&>(f),
|
||||
static_cast<State&&>(state),
|
||||
static_cast<T&&>(t)...
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T, bool condition>
|
||||
struct fold_right_impl<T, when<condition>> : default_ {
|
||||
// with state
|
||||
template <typename Xs, typename S, typename F>
|
||||
static constexpr decltype(auto) apply(Xs&& xs, S&& s, F&& f) {
|
||||
return hana::unpack(static_cast<Xs&&>(xs),
|
||||
detail::variadic_foldr<F, S>{f, s}
|
||||
);
|
||||
}
|
||||
|
||||
// without state
|
||||
template <typename Xs, typename F>
|
||||
static constexpr decltype(auto) apply(Xs&& xs, F&& f) {
|
||||
return hana::unpack(static_cast<Xs&&>(xs),
|
||||
hana::partial(
|
||||
detail::variadic::foldr1,
|
||||
static_cast<F&&>(f)
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FOLD_RIGHT_HPP
|
62
_deps/boost-src/libs/hana/include/boost/hana/for_each.hpp
Normal file
62
_deps/boost-src/libs/hana/include/boost/hana/for_each.hpp
Normal file
@ -0,0 +1,62 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::for_each`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FOR_EACH_HPP
|
||||
#define BOOST_HANA_FOR_EACH_HPP
|
||||
|
||||
#include <boost/hana/fwd/for_each.hpp>
|
||||
|
||||
#include <boost/hana/concept/foldable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
#include <boost/hana/unpack.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs, typename F>
|
||||
constexpr void for_each_t::operator()(Xs&& xs, F&& f) const {
|
||||
using S = typename hana::tag_of<Xs>::type;
|
||||
using ForEach = BOOST_HANA_DISPATCH_IF(for_each_impl<S>,
|
||||
hana::Foldable<S>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Foldable<S>::value,
|
||||
"hana::for_each(xs, f) requires 'xs' to be Foldable");
|
||||
#endif
|
||||
|
||||
return ForEach::apply(static_cast<Xs&&>(xs), static_cast<F&&>(f));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
namespace detail {
|
||||
template <typename F>
|
||||
struct on_each {
|
||||
F f;
|
||||
template <typename ...Xs>
|
||||
constexpr void operator()(Xs&& ...xs) const {
|
||||
using Swallow = int[];
|
||||
(void)Swallow{0, ((void)(*f)(static_cast<Xs&&>(xs)), 0)...};
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template <typename T, bool condition>
|
||||
struct for_each_impl<T, when<condition>> : default_ {
|
||||
template <typename Xs, typename F>
|
||||
static constexpr void apply(Xs&& xs, F&& f) {
|
||||
// We use a pointer instead of a reference to avoid a Clang ICE.
|
||||
hana::unpack(static_cast<Xs&&>(xs),
|
||||
detail::on_each<decltype(&f)>{&f});
|
||||
}
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FOR_EACH_HPP
|
47
_deps/boost-src/libs/hana/include/boost/hana/front.hpp
Normal file
47
_deps/boost-src/libs/hana/include/boost/hana/front.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::front`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FRONT_HPP
|
||||
#define BOOST_HANA_FRONT_HPP
|
||||
|
||||
#include <boost/hana/fwd/front.hpp>
|
||||
|
||||
#include <boost/hana/at.hpp>
|
||||
#include <boost/hana/concept/iterable.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/dispatch.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @cond
|
||||
template <typename Xs>
|
||||
constexpr decltype(auto) front_t::operator()(Xs&& xs) const {
|
||||
using It = typename hana::tag_of<Xs>::type;
|
||||
using Front = BOOST_HANA_DISPATCH_IF(front_impl<It>,
|
||||
hana::Iterable<It>::value
|
||||
);
|
||||
|
||||
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
|
||||
static_assert(hana::Iterable<It>::value,
|
||||
"hana::front(xs) requires 'xs' to be an Iterable");
|
||||
#endif
|
||||
|
||||
return Front::apply(static_cast<Xs&&>(xs));
|
||||
}
|
||||
//! @endcond
|
||||
|
||||
template <typename It, bool condition>
|
||||
struct front_impl<It, when<condition>> : default_ {
|
||||
template <typename Xs>
|
||||
static constexpr decltype(auto) apply(Xs&& xs)
|
||||
{ return hana::at_c<0>(static_cast<Xs&&>(xs)); }
|
||||
};
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FRONT_HPP
|
33
_deps/boost-src/libs/hana/include/boost/hana/functional.hpp
Normal file
33
_deps/boost-src/libs/hana/include/boost/hana/functional.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
/*!
|
||||
@file
|
||||
Defines the @ref group-functional module.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_HPP
|
||||
|
||||
#include <boost/hana/functional/always.hpp>
|
||||
#include <boost/hana/functional/apply.hpp>
|
||||
#include <boost/hana/functional/arg.hpp>
|
||||
#include <boost/hana/functional/capture.hpp>
|
||||
#include <boost/hana/functional/compose.hpp>
|
||||
#include <boost/hana/functional/curry.hpp>
|
||||
#include <boost/hana/functional/demux.hpp>
|
||||
#include <boost/hana/functional/fix.hpp>
|
||||
#include <boost/hana/functional/flip.hpp>
|
||||
#include <boost/hana/functional/id.hpp>
|
||||
#include <boost/hana/functional/infix.hpp>
|
||||
#include <boost/hana/functional/iterate.hpp>
|
||||
#include <boost/hana/functional/lockstep.hpp>
|
||||
#include <boost/hana/functional/on.hpp>
|
||||
#include <boost/hana/functional/overload.hpp>
|
||||
#include <boost/hana/functional/overload_linearly.hpp>
|
||||
#include <boost/hana/functional/partial.hpp>
|
||||
#include <boost/hana/functional/placeholder.hpp>
|
||||
#include <boost/hana/functional/reverse_partial.hpp>
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_HPP
|
@ -0,0 +1,64 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::always`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_ALWAYS_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_ALWAYS_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/create.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Return a constant function returning `x` regardless of the
|
||||
//! argument(s) it is invoked with.
|
||||
//!
|
||||
//! Specifically, `always(x)` is a function such that
|
||||
//! @code
|
||||
//! always(x)(y...) == x
|
||||
//! @endcode
|
||||
//! for any `y...`. A copy of `x` is made and it is owned by the
|
||||
//! `always(x)` function. When `always(x)` is called, it will return
|
||||
//! a reference to the `x` it owns. This reference is valid as long
|
||||
//! as `always(x)` is in scope.
|
||||
//!
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/always.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto always = [](auto&& x) {
|
||||
return [perfect-capture](auto const& ...y) -> decltype(auto) {
|
||||
return forwarded(x);
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename T>
|
||||
struct _always {
|
||||
T val_;
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr T const& operator()(Args const& ...) const&
|
||||
{ return val_; }
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr T& operator()(Args const& ...) &
|
||||
{ return val_; }
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr T operator()(Args const& ...) &&
|
||||
{ return std::move(val_); }
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr detail::create<_always> always{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_ALWAYS_HPP
|
@ -0,0 +1,85 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::apply`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_APPLY_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_APPLY_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Invokes a Callable with the given arguments.
|
||||
//!
|
||||
//! This is equivalent to [std::invoke][1] that will be added in C++17.
|
||||
//! However, `apply` is a function object instead of a function, which
|
||||
//! makes it possible to pass it to higher-order algorithms.
|
||||
//!
|
||||
//!
|
||||
//! @param f
|
||||
//! A [Callable][2] to be invoked with the given arguments.
|
||||
//!
|
||||
//! @param x...
|
||||
//! The arguments to call `f` with. The number of `x...` must match the
|
||||
//! arity of `f`.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/functional/apply.cpp
|
||||
//!
|
||||
//! [1]: http://en.cppreference.com/w/cpp/utility/functional/invoke
|
||||
//! [2]: http://en.cppreference.com/w/cpp/named_req/Callable
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto apply = [](auto&& f, auto&& ...x) -> decltype(auto) {
|
||||
return forwarded(f)(forwarded(x)...);
|
||||
};
|
||||
#else
|
||||
struct apply_t {
|
||||
template <typename F, typename... Args>
|
||||
constexpr auto operator()(F&& f, Args&&... args) const ->
|
||||
decltype(static_cast<F&&>(f)(static_cast<Args&&>(args)...))
|
||||
{
|
||||
return static_cast<F&&>(f)(static_cast<Args&&>(args)...);
|
||||
}
|
||||
|
||||
template <typename Base, typename T, typename Derived>
|
||||
constexpr auto operator()(T Base::*pmd, Derived&& ref) const ->
|
||||
decltype(static_cast<Derived&&>(ref).*pmd)
|
||||
{
|
||||
return static_cast<Derived&&>(ref).*pmd;
|
||||
}
|
||||
|
||||
template <typename PMD, typename Pointer>
|
||||
constexpr auto operator()(PMD pmd, Pointer&& ptr) const ->
|
||||
decltype((*static_cast<Pointer&&>(ptr)).*pmd)
|
||||
{
|
||||
return (*static_cast<Pointer&&>(ptr)).*pmd;
|
||||
}
|
||||
|
||||
template <typename Base, typename T, typename Derived, typename... Args>
|
||||
constexpr auto operator()(T Base::*pmf, Derived&& ref, Args&&... args) const ->
|
||||
decltype((static_cast<Derived&&>(ref).*pmf)(static_cast<Args&&>(args)...))
|
||||
{
|
||||
return (static_cast<Derived&&>(ref).*pmf)(static_cast<Args&&>(args)...);
|
||||
}
|
||||
|
||||
template <typename PMF, typename Pointer, typename... Args>
|
||||
constexpr auto operator()(PMF pmf, Pointer&& ptr, Args&& ...args) const ->
|
||||
decltype(((*static_cast<Pointer&&>(ptr)).*pmf)(static_cast<Args&&>(args)...))
|
||||
{
|
||||
return ((*static_cast<Pointer&&>(ptr)).*pmf)(static_cast<Args&&>(args)...);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr apply_t apply{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_APPLY_HPP
|
141
_deps/boost-src/libs/hana/include/boost/hana/functional/arg.hpp
Normal file
141
_deps/boost-src/libs/hana/include/boost/hana/functional/arg.hpp
Normal file
@ -0,0 +1,141 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::arg`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_ARG_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_ARG_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Return the `n`th passed argument.
|
||||
//!
|
||||
//! Specifically, `arg<n>(x1, ..., xn, ..., xm)` is equivalent to `xn`.
|
||||
//! Note that indexing starts at 1, so `arg<1>` returns the 1st argument,
|
||||
//! `arg<2>` the 2nd and so on. Using `arg<0>` is an error. Passing
|
||||
//! less than `n` arguments to `arg<n>` is also an error.
|
||||
//!
|
||||
//!
|
||||
//! @tparam n
|
||||
//! An unsigned integer representing the argument to return. `n` must be
|
||||
//! positive (meaning nonzero).
|
||||
//!
|
||||
//! @param x1, ..., xm
|
||||
//! A variadic pack of arguments from which the `n`th one is returned.
|
||||
//!
|
||||
//!
|
||||
//! @internal
|
||||
//! ### Discussion: could `n` be dynamic?
|
||||
//! We could have chosen `arg` to be used like `arg(n)(x...)` instead of
|
||||
//! `arg<n>(x...)`. Provided all the arguments were of the same type, it
|
||||
//! would then be possible for `n` to only be known at runtime. However,
|
||||
//! we would then lose the ability to assert the in-boundedness of `n`
|
||||
//! statically.
|
||||
//!
|
||||
//! ### Rationale for `n` being a non-type template parameter
|
||||
//! I claim that the only interesting use case is with a compile-time
|
||||
//! `n`, which means that the usage would become `arg(int_<n>)(x...)`,
|
||||
//! which is more cumbersome to write than `arg<n>(x...)`. This is open
|
||||
//! for discussion.
|
||||
//! @endinternal
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/arg.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <std::size_t n>
|
||||
constexpr auto arg = [](auto&& x1, ..., auto&& xm) -> decltype(auto) {
|
||||
return forwarded(xn);
|
||||
};
|
||||
#else
|
||||
template <std::size_t n, typename = void>
|
||||
struct arg_t;
|
||||
|
||||
template <>
|
||||
struct arg_t<1> {
|
||||
template <typename X1, typename ...Xn>
|
||||
constexpr X1 operator()(X1&& x1, Xn&& ...) const
|
||||
{ return static_cast<X1&&>(x1); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct arg_t<2> {
|
||||
template <typename X1, typename X2, typename ...Xn>
|
||||
constexpr X2 operator()(X1&&, X2&& x2, Xn&& ...) const
|
||||
{ return static_cast<X2&&>(x2); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct arg_t<3> {
|
||||
template <typename X1, typename X2, typename X3, typename ...Xn>
|
||||
constexpr X3 operator()(X1&&, X2&&, X3&& x3, Xn&& ...) const
|
||||
{ return static_cast<X3&&>(x3); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct arg_t<4> {
|
||||
template <typename X1, typename X2, typename X3, typename X4, typename ...Xn>
|
||||
constexpr X4 operator()(X1&&, X2&&, X3&&, X4&& x4, Xn&& ...) const
|
||||
{ return static_cast<X4&&>(x4); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct arg_t<5> {
|
||||
template <typename X1, typename X2, typename X3, typename X4,
|
||||
typename X5, typename ...Xn>
|
||||
constexpr X5 operator()(X1&&, X2&&, X3&&, X4&&, X5&& x5, Xn&& ...) const
|
||||
{ return static_cast<X5&&>(x5); }
|
||||
};
|
||||
|
||||
template <std::size_t n, typename>
|
||||
struct arg_t {
|
||||
static_assert(n > 0,
|
||||
"invalid usage of boost::hana::arg<n> with n == 0");
|
||||
|
||||
template <typename X1, typename X2, typename X3, typename X4,
|
||||
typename X5, typename ...Xn>
|
||||
constexpr decltype(auto)
|
||||
operator()(X1&&, X2&&, X3&&, X4&&, X5&&, Xn&& ...xn) const {
|
||||
static_assert(sizeof...(xn) >= n - 5,
|
||||
"invalid usage of boost::hana::arg<n> with too few arguments");
|
||||
|
||||
// Since compilers will typically try to continue for a bit after
|
||||
// an error/static assertion, we must avoid sending the compiler
|
||||
// in a very long computation if n == 0.
|
||||
return arg_t<n == 0 ? 1 : n - 5>{}(static_cast<Xn&&>(xn)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
struct arg_t<n, std::enable_if_t<(n > 25)>> {
|
||||
template <
|
||||
typename X1, typename X2, typename X3, typename X4, typename X5,
|
||||
typename X6, typename X7, typename X8, typename X9, typename X10,
|
||||
typename X11, typename X12, typename X13, typename X14, typename X15,
|
||||
typename X16, typename X17, typename X18, typename X19, typename X20,
|
||||
typename X21, typename X22, typename X23, typename X24, typename X25,
|
||||
typename ...Xn>
|
||||
constexpr decltype(auto)
|
||||
operator()(X1&&, X2&&, X3&&, X4&&, X5&&,
|
||||
X6&&, X7&&, X8&&, X9&&, X10&&,
|
||||
X11&&, X12&&, X13&&, X14&&, X15&&,
|
||||
X16&&, X17&&, X18&&, X19&&, X20&&,
|
||||
X21&&, X22&&, X23&&, X24&&, X25&&, Xn&& ...xn) const
|
||||
{ return arg_t<n - 25>{}(static_cast<Xn&&>(xn)...); }
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr arg_t<n> arg{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_ARG_HPP
|
@ -0,0 +1,112 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::capture`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_CAPTURE_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_CAPTURE_HPP
|
||||
|
||||
#include <boost/hana/basic_tuple.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
#include <boost/hana/functional/partial.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Create a function capturing the given variables.
|
||||
//!
|
||||
//! Given 0 or more variables, `capture` creates a closure that can be
|
||||
//! used to partially apply a function. This is very similar to `partial`,
|
||||
//! except that `capture` allows the partially applied function to be
|
||||
//! specified later. Specifically, `capture(vars...)` is a function object
|
||||
//! taking a function `f` and returning `f` partially applied to `vars...`.
|
||||
//! In other words,
|
||||
//! @code
|
||||
//! capture(vars...)(f)(args...) == f(vars..., args...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! @note
|
||||
//! The arity of `f` must match the total number of arguments passed to
|
||||
//! it, i.e. `sizeof...(vars) + sizeof...(args)`.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/functional/capture.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto capture = [](auto&& ...variables) {
|
||||
return [perfect-capture](auto&& f) {
|
||||
return [perfect-capture](auto&& ...args) -> decltype(auto) {
|
||||
return forwarded(f)(forwarded(variables)..., forwarded(args)...);
|
||||
};
|
||||
};
|
||||
};
|
||||
#else
|
||||
namespace detail {
|
||||
template <typename F, typename Closure, std::size_t ...i>
|
||||
constexpr auto apply_capture(F&& f, Closure&& closure, std::index_sequence<i...>) {
|
||||
return hana::partial(static_cast<F&&>(f),
|
||||
hana::at_c<i>(static_cast<Closure&&>(closure).storage_)...
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
struct capture_t;
|
||||
|
||||
struct make_capture_t {
|
||||
struct secret { };
|
||||
template <typename ...X>
|
||||
constexpr capture_t<typename detail::decay<X>::type...>
|
||||
operator()(X&& ...x) const {
|
||||
return {secret{}, static_cast<X&&>(x)...};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ...X>
|
||||
struct capture_t {
|
||||
template <typename ...Y>
|
||||
constexpr capture_t(make_capture_t::secret, Y&& ...y)
|
||||
: storage_{static_cast<Y&&>(y)...}
|
||||
{ }
|
||||
|
||||
basic_tuple<X...> storage_;
|
||||
|
||||
template <typename F>
|
||||
constexpr auto operator()(F&& f) const& {
|
||||
return detail::apply_capture(
|
||||
static_cast<F&&>(f), *this,
|
||||
std::make_index_sequence<sizeof...(X)>{}
|
||||
);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
constexpr auto operator()(F&& f) & {
|
||||
return detail::apply_capture(
|
||||
static_cast<F&&>(f), *this,
|
||||
std::make_index_sequence<sizeof...(X)>{}
|
||||
);
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
constexpr auto operator()(F&& f) && {
|
||||
return detail::apply_capture(
|
||||
static_cast<F&&>(f), static_cast<capture_t&&>(*this),
|
||||
std::make_index_sequence<sizeof...(X)>{}
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_capture_t capture{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_CAPTURE_HPP
|
@ -0,0 +1,108 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::compose`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_COMPOSE_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_COMPOSE_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/create.hpp>
|
||||
#include <boost/hana/detail/variadic/foldl1.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Return the composition of two functions or more.
|
||||
//!
|
||||
//! `compose` is defined inductively. When given more than two functions,
|
||||
//! `compose(f, g, h...)` is equivalent to `compose(f, compose(g, h...))`.
|
||||
//! When given two functions, `compose(f, g)` is a function such that
|
||||
//! @code
|
||||
//! compose(f, g)(x, y...) == f(g(x), y...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! If you need composition of the form `f(g(x, y...))`, use `demux` instead.
|
||||
//!
|
||||
//! @note
|
||||
//! `compose` is an associative operation; `compose(f, compose(g, h))`
|
||||
//! is equivalent to `compose(compose(f, g), h)`.
|
||||
//!
|
||||
//! @internal
|
||||
//! ### Proof of associativity
|
||||
//!
|
||||
//! @code
|
||||
//! compose(f, compose(g, h))(x, xs...) == f(compose(g, h)(x), xs...)
|
||||
//! == f(g(h(x)), xs...)
|
||||
//!
|
||||
//! compose(compose(f, g), h)(x, xs...) == compose(f, g)(h(x), xs...)
|
||||
//! == f(g(h(x)), xs...)
|
||||
//! @endcode
|
||||
//! @endinternal
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/compose.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto compose = [](auto&& f1, auto&& f2, ..., auto&& fn) {
|
||||
return [perfect-capture](auto&& x, auto&& ...xs) -> decltype(auto) {
|
||||
return forwarded(f1)(
|
||||
forwarded(f2)(
|
||||
...
|
||||
forwarded(fn)(forwarded(x))
|
||||
),
|
||||
forwarded(xs)...
|
||||
);
|
||||
}
|
||||
};
|
||||
#else
|
||||
template <typename F, typename G>
|
||||
struct _compose {
|
||||
F f; G g;
|
||||
|
||||
template <typename X, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(X&& x, Xs&& ...xs) const& {
|
||||
return f(
|
||||
g(static_cast<X&&>(x)),
|
||||
static_cast<Xs&&>(xs)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename X, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(X&& x, Xs&& ...xs) & {
|
||||
return f(
|
||||
g(static_cast<X&&>(x)),
|
||||
static_cast<Xs&&>(xs)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename X, typename ...Xs>
|
||||
constexpr decltype(auto) operator()(X&& x, Xs&& ...xs) && {
|
||||
return std::move(f)(
|
||||
std::move(g)(static_cast<X&&>(x)),
|
||||
static_cast<Xs&&>(xs)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
struct _make_compose {
|
||||
template <typename F, typename G, typename ...H>
|
||||
constexpr decltype(auto) operator()(F&& f, G&& g, H&& ...h) const {
|
||||
return detail::variadic::foldl1(detail::create<_compose>{},
|
||||
static_cast<F&&>(f),
|
||||
static_cast<G&&>(g),
|
||||
static_cast<H&&>(h)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr _make_compose compose{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_COMPOSE_HPP
|
@ -0,0 +1,170 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::curry`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_CURRY_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_CURRY_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
#include <boost/hana/functional/apply.hpp>
|
||||
#include <boost/hana/functional/partial.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Curry a function up to the given number of arguments.
|
||||
//!
|
||||
//! [Currying][Wikipedia.currying] is a technique in which we consider a
|
||||
//! function taking multiple arguments (or, equivalently, a tuple of
|
||||
//! arguments), and turn it into a function which takes a single argument
|
||||
//! and returns a function to handle the remaining arguments. To help
|
||||
//! visualize, let's denote the type of a function `f` which takes
|
||||
//! arguments of types `X1, ..., Xn` and returns a `R` as
|
||||
//! @code
|
||||
//! (X1, ..., Xn) -> R
|
||||
//! @endcode
|
||||
//!
|
||||
//! Then, currying is the process of taking `f` and turning it into an
|
||||
//! equivalent function (call it `g`) of type
|
||||
//! @code
|
||||
//! X1 -> (X2 -> (... -> (Xn -> R)))
|
||||
//! @endcode
|
||||
//!
|
||||
//! This gives us the following equivalence, where `x1`, ..., `xn` are
|
||||
//! objects of type `X1`, ..., `Xn` respectively:
|
||||
//! @code
|
||||
//! f(x1, ..., xn) == g(x1)...(xn)
|
||||
//! @endcode
|
||||
//!
|
||||
//! Currying can be useful in several situations, especially when working
|
||||
//! with higher-order functions.
|
||||
//!
|
||||
//! This `curry` utility is an implementation of currying in C++.
|
||||
//! Specifically, `curry<n>(f)` is a function such that
|
||||
//! @code
|
||||
//! curry<n>(f)(x1)...(xn) == f(x1, ..., xn)
|
||||
//! @endcode
|
||||
//!
|
||||
//! Note that the `n` has to be specified explicitly because the existence
|
||||
//! of functions with variadic arguments in C++ make it impossible to know
|
||||
//! when currying should stop.
|
||||
//!
|
||||
//! Unlike usual currying, this implementation also allows a curried
|
||||
//! function to be called with several arguments at a time. Hence, the
|
||||
//! following always holds
|
||||
//! @code
|
||||
//! curry<n>(f)(x1, ..., xk) == curry<n - k>(f)(x1)...(xk)
|
||||
//! @endcode
|
||||
//!
|
||||
//! Of course, this requires `k` to be less than or equal to `n`; failure
|
||||
//! to satisfy this will trigger a static assertion. This syntax is
|
||||
//! supported because it makes curried functions usable where normal
|
||||
//! functions are expected.
|
||||
//!
|
||||
//! Another "extension" is that `curry<0>(f)` is supported: `curry<0>(f)`
|
||||
//! is a nullary function; whereas the classical definition for currying
|
||||
//! seems to leave this case undefined, as nullary functions don't make
|
||||
//! much sense in purely functional languages.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/functional/curry.cpp
|
||||
//!
|
||||
//!
|
||||
//! [Wikipedia.currying]: http://en.wikipedia.org/wiki/Currying
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <std::size_t n>
|
||||
constexpr auto curry = [](auto&& f) {
|
||||
return [perfect-capture](auto&& x1) {
|
||||
return [perfect-capture](auto&& x2) {
|
||||
...
|
||||
return [perfect-capture](auto&& xn) -> decltype(auto) {
|
||||
return forwarded(f)(
|
||||
forwarded(x1), forwarded(x2), ..., forwarded(xn)
|
||||
);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <std::size_t n, typename F>
|
||||
struct curry_t;
|
||||
|
||||
template <std::size_t n>
|
||||
struct make_curry_t {
|
||||
template <typename F>
|
||||
constexpr curry_t<n, typename detail::decay<F>::type>
|
||||
operator()(F&& f) const { return {static_cast<F&&>(f)}; }
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_curry_t<n> curry{};
|
||||
|
||||
namespace curry_detail { namespace {
|
||||
template <std::size_t n>
|
||||
constexpr make_curry_t<n> curry_or_call{};
|
||||
|
||||
template <>
|
||||
constexpr auto curry_or_call<0> = apply;
|
||||
}}
|
||||
|
||||
template <std::size_t n, typename F>
|
||||
struct curry_t {
|
||||
F f;
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) const& {
|
||||
static_assert(sizeof...(x) <= n,
|
||||
"too many arguments provided to boost::hana::curry");
|
||||
return curry_detail::curry_or_call<n - sizeof...(x)>(
|
||||
partial(f, static_cast<X&&>(x)...)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) & {
|
||||
static_assert(sizeof...(x) <= n,
|
||||
"too many arguments provided to boost::hana::curry");
|
||||
return curry_detail::curry_or_call<n - sizeof...(x)>(
|
||||
partial(f, static_cast<X&&>(x)...)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) && {
|
||||
static_assert(sizeof...(x) <= n,
|
||||
"too many arguments provided to boost::hana::curry");
|
||||
return curry_detail::curry_or_call<n - sizeof...(x)>(
|
||||
partial(std::move(f), static_cast<X&&>(x)...)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct curry_t<0, F> {
|
||||
F f;
|
||||
|
||||
constexpr decltype(auto) operator()() const&
|
||||
{ return f(); }
|
||||
|
||||
constexpr decltype(auto) operator()() &
|
||||
{ return f(); }
|
||||
|
||||
constexpr decltype(auto) operator()() &&
|
||||
{ return std::move(f)(); }
|
||||
};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_CURRY_HPP
|
@ -0,0 +1,269 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::demux`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_DEMUX_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_DEMUX_HPP
|
||||
|
||||
#include <boost/hana/basic_tuple.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Invoke a function with the results of invoking other functions
|
||||
//! on its arguments.
|
||||
//!
|
||||
//! Specifically, `demux(f)(g...)` is a function such that
|
||||
//! @code
|
||||
//! demux(f)(g...)(x...) == f(g(x...)...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! Each `g` is called with all the arguments, and then `f` is called
|
||||
//! with the result of each `g`. Hence, the arity of `f` must match
|
||||
//! the number of `g`s.
|
||||
//!
|
||||
//! This is called `demux` because of a vague similarity between this
|
||||
//! device and a demultiplexer in signal processing. `demux` takes what
|
||||
//! can be seen as a continuation (`f`), a bunch of functions to split a
|
||||
//! signal (`g...`) and zero or more arguments representing the signal
|
||||
//! (`x...`). Then, it calls the continuation with the result of
|
||||
//! splitting the signal with whatever functions where given.
|
||||
//!
|
||||
//! @note
|
||||
//! When used with two functions only, `demux` is associative. In other
|
||||
//! words (and noting `demux(f, g) = demux(f)(g)` to ease the notation),
|
||||
//! it is true that `demux(demux(f, g), h) == demux(f, demux(g, h))`.
|
||||
//!
|
||||
//!
|
||||
//! Signature
|
||||
//! ---------
|
||||
//! The signature of `demux` is
|
||||
//! \f[
|
||||
//! \mathtt{demux} :
|
||||
//! (B_1 \times \dotsb \times B_n \to C)
|
||||
//! \to ((A_1 \times \dotsb \times A_n \to B_1)
|
||||
//! \times \dotsb
|
||||
//! \times (A_1 \times \dotsb \times A_n \to B_n))
|
||||
//! \to (A_1 \times \dotsb \times A_n \to C)
|
||||
//! \f]
|
||||
//!
|
||||
//! This can be rewritten more tersely as
|
||||
//! \f[
|
||||
//! \mathtt{demux} :
|
||||
//! \left(\prod_{i=1}^n B_i \to C \right)
|
||||
//! \to \prod_{j=1}^n \left(\prod_{i=1}^n A_i \to B_j \right)
|
||||
//! \to \left(\prod_{i=1}^n A_i \to C \right)
|
||||
//! \f]
|
||||
//!
|
||||
//!
|
||||
//! Link with normal composition
|
||||
//! ----------------------------
|
||||
//! The signature of `compose` is
|
||||
//! \f[
|
||||
//! \mathtt{compose} : (B \to C) \times (A \to B) \to (A \to C)
|
||||
//! \f]
|
||||
//!
|
||||
//! A valid observation is that this coincides exactly with the type
|
||||
//! of `demux` when used with a single unary function. Actually, both
|
||||
//! functions are equivalent:
|
||||
//! @code
|
||||
//! demux(f)(g)(x) == compose(f, g)(x)
|
||||
//! @endcode
|
||||
//!
|
||||
//! However, let's now consider the curried version of `compose`,
|
||||
//! `curry<2>(compose)`:
|
||||
//! \f[
|
||||
//! \mathtt{curry_2(compose)} : (B \to C) \to ((A \to B) \to (A \to C))
|
||||
//! \f]
|
||||
//!
|
||||
//! For the rest of this explanation, we'll just consider the curried
|
||||
//! version of `compose` and so we'll use `compose` instead of
|
||||
//! `curry<2>(compose)` to lighten the notation. With currying, we can
|
||||
//! now consider `compose` applied to itself:
|
||||
//! \f[
|
||||
//! \mathtt{compose(compose, compose)} :
|
||||
//! (B \to C) \to (A_1 \to A_2 \to B) \to (A_1 \to A_2 \to C)
|
||||
//! \f]
|
||||
//!
|
||||
//! If we uncurry deeply the above expression, we obtain
|
||||
//! \f[
|
||||
//! \mathtt{compose(compose, compose)} :
|
||||
//! (B \to C) \times (A_1 \times A_2 \to B) \to (A_1 \times A_2 \to C)
|
||||
//! \f]
|
||||
//!
|
||||
//! This signature is exactly the same as that of `demux` when given a
|
||||
//! single binary function, and indeed they are equivalent definitions.
|
||||
//! We can also generalize this further by considering
|
||||
//! `compose(compose(compose, compose), compose)`:
|
||||
//! \f[
|
||||
//! \mathtt{compose(compose(compose, compose), compose)} :
|
||||
//! (B \to C) \to (A_1 \to A_2 \to A_3 \to B)
|
||||
//! \to (A_1 \to A_2 \to A_3 \to C)
|
||||
//! \f]
|
||||
//!
|
||||
//! which uncurries to
|
||||
//! \f[
|
||||
//! \mathtt{compose(compose(compose, compose), compose)} :
|
||||
//! (B \to C) \times (A_1 \times A_2 \times A_3 \to B)
|
||||
//! \to (A_1 \times A_2 \times A_3 \to C)
|
||||
//! \f]
|
||||
//!
|
||||
//! This signature is exactly the same as that of `demux` when given a
|
||||
//! single ternary function. Hence, for a single n-ary function `g`,
|
||||
//! `demux(f)(g)` is equivalent to the n-times composition of `compose`
|
||||
//! with itself, applied to `g` and `f`:
|
||||
//! @code
|
||||
//! demux(f)(g) == fold_left([compose, ..., compose], id, compose)(g, f)
|
||||
//! // ^^^^^^^^^^^^^^^^^^^^^ n times
|
||||
//! @endcode
|
||||
//!
|
||||
//! More information on this insight can be seen [here][1]. Also, I'm
|
||||
//! not sure how this insight could be generalized to more than one
|
||||
//! function `g`, or if that is even possible.
|
||||
//!
|
||||
//!
|
||||
//! Proof of associativity in the binary case
|
||||
//! -----------------------------------------
|
||||
//! As explained above, `demux` is associative when it is used with
|
||||
//! two functions only. Indeed, given functions `f`, `g` and `h` with
|
||||
//! suitable signatures, we have
|
||||
//! @code
|
||||
//! demux(f)(demux(g)(h))(x...) == f(demux(g)(h)(x...))
|
||||
//! == f(g(h(x...)))
|
||||
//! @endcode
|
||||
//!
|
||||
//! On the other hand, we have
|
||||
//! @code
|
||||
//! demux(demux(f)(g))(h)(x...) == demux(f)(g)(h(x...))
|
||||
//! == f(g(h(x...)))
|
||||
//! @endcode
|
||||
//!
|
||||
//! and hence `demux` is associative in the binary case.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/functional/demux.cpp
|
||||
//!
|
||||
//! [1]: http://stackoverflow.com/q/5821089/627587
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto demux = [](auto&& f) {
|
||||
return [perfect-capture](auto&& ...g) {
|
||||
return [perfect-capture](auto&& ...x) -> decltype(auto) {
|
||||
// x... can't be forwarded unless there is a single g
|
||||
// function, or that could cause double-moves.
|
||||
return forwarded(f)(forwarded(g)(x...)...);
|
||||
};
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename F>
|
||||
struct pre_demux_t;
|
||||
|
||||
struct make_pre_demux_t {
|
||||
struct secret { };
|
||||
template <typename F>
|
||||
constexpr pre_demux_t<typename detail::decay<F>::type> operator()(F&& f) const {
|
||||
return {static_cast<F&&>(f)};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Indices, typename F, typename ...G>
|
||||
struct demux_t;
|
||||
|
||||
template <typename F>
|
||||
struct pre_demux_t {
|
||||
F f;
|
||||
|
||||
template <typename ...G>
|
||||
constexpr demux_t<std::make_index_sequence<sizeof...(G)>, F,
|
||||
typename detail::decay<G>::type...>
|
||||
operator()(G&& ...g) const& {
|
||||
return {make_pre_demux_t::secret{}, this->f, static_cast<G&&>(g)...};
|
||||
}
|
||||
|
||||
template <typename ...G>
|
||||
constexpr demux_t<std::make_index_sequence<sizeof...(G)>, F,
|
||||
typename detail::decay<G>::type...>
|
||||
operator()(G&& ...g) && {
|
||||
return {make_pre_demux_t::secret{}, static_cast<F&&>(this->f), static_cast<G&&>(g)...};
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t ...n, typename F, typename ...G>
|
||||
struct demux_t<std::index_sequence<n...>, F, G...> {
|
||||
template <typename ...T>
|
||||
constexpr demux_t(make_pre_demux_t::secret, T&& ...t)
|
||||
: storage_{static_cast<T&&>(t)...}
|
||||
{ }
|
||||
|
||||
basic_tuple<F, G...> storage_;
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) const& {
|
||||
return hana::at_c<0>(storage_)(
|
||||
hana::at_c<n+1>(storage_)(x...)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) & {
|
||||
return hana::at_c<0>(storage_)(
|
||||
hana::at_c<n+1>(storage_)(x...)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) && {
|
||||
return static_cast<F&&>(hana::at_c<0>(storage_))(
|
||||
static_cast<G&&>(hana::at_c<n+1>(storage_))(x...)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename G>
|
||||
struct demux_t<std::index_sequence<0>, F, G> {
|
||||
template <typename ...T>
|
||||
constexpr demux_t(make_pre_demux_t::secret, T&& ...t)
|
||||
: storage_{static_cast<T&&>(t)...}
|
||||
{ }
|
||||
|
||||
basic_tuple<F, G> storage_;
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) const& {
|
||||
return hana::at_c<0>(storage_)(
|
||||
hana::at_c<1>(storage_)(static_cast<X&&>(x)...)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) & {
|
||||
return hana::at_c<0>(storage_)(
|
||||
hana::at_c<1>(storage_)(static_cast<X&&>(x)...)
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) && {
|
||||
return static_cast<F&&>(hana::at_c<0>(storage_))(
|
||||
static_cast<G&&>(hana::at_c<1>(storage_))(static_cast<X&&>(x)...)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_pre_demux_t demux{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_DEMUX_HPP
|
@ -0,0 +1,83 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::fix`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_FIX_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_FIX_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/create.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Return a function computing the fixed point of a function.
|
||||
//!
|
||||
//! `fix` is an implementation of the [Y-combinator][], also called the
|
||||
//! fixed-point combinator. It encodes the idea of recursion, and in fact
|
||||
//! any recursive function can be written in terms of it.
|
||||
//!
|
||||
//! Specifically, `fix(f)` is a function such that
|
||||
//! @code
|
||||
//! fix(f)(x...) == f(fix(f), x...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! This definition allows `f` to use its first argument as a continuation
|
||||
//! to call itself recursively. Indeed, if `f` calls its first argument
|
||||
//! with `y...`, it is equivalent to calling `f(fix(f), y...)` per the
|
||||
//! above equation.
|
||||
//!
|
||||
//! Most of the time, it is more convenient and efficient to define
|
||||
//! recursive functions without using a fixed-point combinator. However,
|
||||
//! there are some cases where `fix` provides either more flexibility
|
||||
//! (e.g. the ability to change the callback inside `f`) or makes it
|
||||
//! possible to write functions that couldn't be defined recursively
|
||||
//! otherwise.
|
||||
//!
|
||||
//! @param f
|
||||
//! A function called as `f(self, x...)`, where `x...` are the arguments
|
||||
//! in the `fix(f)(x...)` expression and `self` is `fix(f)`.
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/fix.cpp
|
||||
//!
|
||||
//! [Y-combinator]: http://en.wikipedia.org/wiki/Fixed-point_combinator
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto fix = [](auto&& f) {
|
||||
return [perfect-capture](auto&& ...x) -> decltype(auto) {
|
||||
return forwarded(f)(fix(f), forwarded(x)...);
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename F>
|
||||
struct fix_t;
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr detail::create<fix_t> fix{};
|
||||
|
||||
template <typename F>
|
||||
struct fix_t {
|
||||
F f;
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) const&
|
||||
{ return f(fix(f), static_cast<X&&>(x)...); }
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) &
|
||||
{ return f(fix(f), static_cast<X&&>(x)...); }
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) &&
|
||||
{ return std::move(f)(fix(f), static_cast<X&&>(x)...); }
|
||||
};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_FIX_HPP
|
@ -0,0 +1,73 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::flip`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_FLIP_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_FLIP_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/create.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Invoke a function with its two first arguments reversed.
|
||||
//!
|
||||
//! Specifically, `flip(f)` is a function such that
|
||||
//! @code
|
||||
//! flip(f)(x, y, z...) == f(y, x, z...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/flip.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto flip = [](auto&& f) {
|
||||
return [perfect-capture](auto&& x, auto&& y, auto&& ...z) -> decltype(auto) {
|
||||
return forwarded(f)(forwarded(y), forwarded(x), forwarded(z)...);
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename F>
|
||||
struct flip_t {
|
||||
F f;
|
||||
|
||||
template <typename X, typename Y, typename ...Z>
|
||||
constexpr decltype(auto) operator()(X&& x, Y&& y, Z&& ...z) const& {
|
||||
return f(
|
||||
static_cast<Y&&>(y),
|
||||
static_cast<X&&>(x),
|
||||
static_cast<Z&&>(z)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename X, typename Y, typename ...Z>
|
||||
constexpr decltype(auto) operator()(X&& x, Y&& y, Z&& ...z) & {
|
||||
return f(
|
||||
static_cast<Y&&>(y),
|
||||
static_cast<X&&>(x),
|
||||
static_cast<Z&&>(z)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename X, typename Y, typename ...Z>
|
||||
constexpr decltype(auto) operator()(X&& x, Y&& y, Z&& ...z) && {
|
||||
return std::move(f)(
|
||||
static_cast<Y&&>(y),
|
||||
static_cast<X&&>(x),
|
||||
static_cast<Z&&>(z)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr detail::create<flip_t> flip{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_FLIP_HPP
|
@ -0,0 +1,38 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::id`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_ID_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_ID_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! The identity function -- returns its argument unchanged.
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/id.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto id = [](auto&& x) -> decltype(auto) {
|
||||
return forwarded(x);
|
||||
};
|
||||
#else
|
||||
struct id_t {
|
||||
template <typename T>
|
||||
constexpr T operator()(T&& t) const {
|
||||
return static_cast<T&&>(t);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr id_t id{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_ID_HPP
|
@ -0,0 +1,185 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::infix`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_INFIX_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_INFIX_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
#include <boost/hana/functional/partial.hpp>
|
||||
#include <boost/hana/functional/reverse_partial.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Return an equivalent function that can also be applied in infix
|
||||
//! notation.
|
||||
//!
|
||||
//! Specifically, `infix(f)` is an object such that:
|
||||
//! @code
|
||||
//! infix(f)(x1, ..., xn) == f(x1, ..., xn)
|
||||
//! x ^infix(f)^ y == f(x, y)
|
||||
//! @endcode
|
||||
//!
|
||||
//! Hence, the returned function can still be applied using the usual
|
||||
//! function call syntax, but it also gains the ability to be applied in
|
||||
//! infix notation. The infix syntax allows a great deal of expressiveness,
|
||||
//! especially when used in combination with some higher order algorithms.
|
||||
//! Since `operator^` is left-associative, `x ^infix(f)^ y` is actually
|
||||
//! parsed as `(x ^infix(f))^ y`. However, for flexibility, the order in
|
||||
//! which both arguments are applied in infix notation does not matter.
|
||||
//! Hence, it is always the case that
|
||||
//! @code
|
||||
//! (x ^ infix(f)) ^ y == x ^ (infix(f) ^ y)
|
||||
//! @endcode
|
||||
//!
|
||||
//! However, note that applying more than one argument in infix
|
||||
//! notation to the same side of the operator will result in a
|
||||
//! compile-time assertion:
|
||||
//! @code
|
||||
//! (infix(f) ^ x) ^ y; // compile-time assertion
|
||||
//! y ^ (x ^ infix(f)); // compile-time assertion
|
||||
//! @endcode
|
||||
//!
|
||||
//! Additionally, a function created with `infix` may be partially applied
|
||||
//! in infix notation. Specifically,
|
||||
//! @code
|
||||
//! (x ^ infix(f))(y1, ..., yn) == f(x, y1, ..., yn)
|
||||
//! (infix(f) ^ y)(x1, ..., xn) == f(x1, ..., xn, y)
|
||||
//! @endcode
|
||||
//!
|
||||
//! @internal
|
||||
//! ### Rationales
|
||||
//! 1. The `^` operator was chosen because it is left-associative and
|
||||
//! has a low enough priority so that most expressions will render
|
||||
//! the expected behavior.
|
||||
//! 2. The operator can't be customimzed because that would require more
|
||||
//! sophistication in the implementation; I want to keep it as simple
|
||||
//! as possible. There is also an advantage in having a uniform syntax
|
||||
//! for infix application.
|
||||
//! @endinternal
|
||||
//!
|
||||
//! @param f
|
||||
//! The function which gains the ability to be applied in infix notation.
|
||||
//! The function must be at least binary; a compile-time error will be
|
||||
//! triggered otherwise.
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/infix.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto infix = [](auto f) {
|
||||
return unspecified;
|
||||
};
|
||||
#else
|
||||
namespace infix_detail {
|
||||
// This needs to be in the same namespace as `operator^` so it can be
|
||||
// found by ADL.
|
||||
template <bool left, bool right, typename F>
|
||||
struct infix_t {
|
||||
F f;
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) const&
|
||||
{ return f(static_cast<X&&>(x)...); }
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) &
|
||||
{ return f(static_cast<X&&>(x)...); }
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) &&
|
||||
{ return std::move(f)(static_cast<X&&>(x)...); }
|
||||
};
|
||||
|
||||
template <bool left, bool right>
|
||||
struct make_infix {
|
||||
template <typename F>
|
||||
constexpr infix_t<left, right, typename detail::decay<F>::type>
|
||||
operator()(F&& f) const { return {static_cast<F&&>(f)}; }
|
||||
};
|
||||
|
||||
template <bool left, bool right>
|
||||
struct Infix;
|
||||
struct Object;
|
||||
|
||||
template <typename T>
|
||||
struct dispatch { using type = Object; };
|
||||
|
||||
template <bool left, bool right, typename F>
|
||||
struct dispatch<infix_t<left, right, F>> {
|
||||
using type = Infix<left, right>;
|
||||
};
|
||||
|
||||
template <typename, typename>
|
||||
struct bind_infix;
|
||||
|
||||
// infix(f) ^ y
|
||||
template <>
|
||||
struct bind_infix<Infix<false, false>, Object> {
|
||||
template <typename F, typename Y>
|
||||
static constexpr decltype(auto) apply(F&& f, Y&& y) {
|
||||
return make_infix<false, true>{}(
|
||||
hana::reverse_partial(
|
||||
static_cast<F&&>(f), static_cast<Y&&>(y)
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// (x^infix(f)) ^ y
|
||||
template <>
|
||||
struct bind_infix<Infix<true, false>, Object> {
|
||||
template <typename F, typename Y>
|
||||
static constexpr decltype(auto) apply(F&& f, Y&& y) {
|
||||
return static_cast<F&&>(f)(static_cast<Y&&>(y));
|
||||
}
|
||||
};
|
||||
|
||||
// x ^ infix(f)
|
||||
template <>
|
||||
struct bind_infix<Object, Infix<false, false>> {
|
||||
template <typename X, typename F>
|
||||
static constexpr decltype(auto) apply(X&& x, F&& f) {
|
||||
return make_infix<true, false>{}(
|
||||
hana::partial(static_cast<F&&>(f), static_cast<X&&>(x))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// x ^ (infix(f)^y)
|
||||
template <>
|
||||
struct bind_infix<Object, Infix<false, true>> {
|
||||
template <typename X, typename F>
|
||||
static constexpr decltype(auto) apply(X&& x, F&& f) {
|
||||
return static_cast<F&&>(f)(static_cast<X&&>(x));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using strip = typename std::remove_cv<
|
||||
typename std::remove_reference<T>::type
|
||||
>::type;
|
||||
|
||||
template <typename X, typename Y>
|
||||
constexpr decltype(auto) operator^(X&& x, Y&& y) {
|
||||
return bind_infix<
|
||||
typename dispatch<strip<X>>::type,
|
||||
typename dispatch<strip<Y>>::type
|
||||
>::apply(static_cast<X&&>(x), static_cast<Y&&>(y));
|
||||
}
|
||||
} // end namespace infix_detail
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr infix_detail::make_infix<false, false> infix{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_INFIX_HPP
|
@ -0,0 +1,201 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::iterate`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_ITERATE_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_ITERATE_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
#include <boost/hana/functional/partial.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Applies another function `n` times to its argument.
|
||||
//!
|
||||
//! Given a function `f` and an argument `x`, `iterate<n>(f, x)` returns
|
||||
//! the result of applying `f` `n` times to its argument. In other words,
|
||||
//! @code
|
||||
//! iterate<n>(f, x) == f(f( ... f(x)))
|
||||
//! ^^^^^^^^^^ n times total
|
||||
//! @endcode
|
||||
//!
|
||||
//! If `n == 0`, `iterate<n>(f, x)` returns the `x` argument unchanged
|
||||
//! and `f` is never applied. It is important to note that the function
|
||||
//! passed to `iterate<n>` must be a unary function. Indeed, since `f`
|
||||
//! will be called with the result of the previous `f` application, it
|
||||
//! may only take a single argument.
|
||||
//!
|
||||
//! In addition to what's documented above, `iterate` can also be
|
||||
//! partially applied to the function argument out-of-the-box. In
|
||||
//! other words, `iterate<n>(f)` is a function object applying `f`
|
||||
//! `n` times to the argument it is called with, which means that
|
||||
//! @code
|
||||
//! iterate<n>(f)(x) == iterate<n>(f, x)
|
||||
//! @endcode
|
||||
//!
|
||||
//! This is provided for convenience, and it turns out to be especially
|
||||
//! useful in conjunction with higher-order algorithms.
|
||||
//!
|
||||
//!
|
||||
//! Signature
|
||||
//! ---------
|
||||
//! Given a function \f$ f : T \to T \f$ and `x` and argument of data
|
||||
//! type `T`, the signature is
|
||||
//! \f$
|
||||
//! \mathtt{iterate_n} : (T \to T) \times T \to T
|
||||
//! \f$
|
||||
//!
|
||||
//! @tparam n
|
||||
//! An unsigned integer representing the number of times that `f`
|
||||
//! should be applied to its argument.
|
||||
//!
|
||||
//! @param f
|
||||
//! A function to apply `n` times to its argument.
|
||||
//!
|
||||
//! @param x
|
||||
//! The initial value to call `f` with.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/functional/iterate.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <std::size_t n>
|
||||
constexpr auto iterate = [](auto&& f) {
|
||||
return [perfect-capture](auto&& x) -> decltype(auto) {
|
||||
return f(f( ... f(forwarded(x))));
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <std::size_t n, typename = when<true>>
|
||||
struct iterate_t;
|
||||
|
||||
template <>
|
||||
struct iterate_t<0> {
|
||||
template <typename F, typename X>
|
||||
constexpr X operator()(F&&, X&& x) const
|
||||
{ return static_cast<X&&>(x); }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterate_t<1> {
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return f(static_cast<X&&>(x));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterate_t<2> {
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return f(f(static_cast<X&&>(x)));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterate_t<3> {
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return f(f(f(static_cast<X&&>(x))));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterate_t<4> {
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return f(f(f(f(static_cast<X&&>(x)))));
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct iterate_t<5> {
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return f(f(f(f(f(static_cast<X&&>(x))))));
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
struct iterate_t<n, when<(n >= 6) && (n < 12)>> {
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return iterate_t<n - 6>{}(f,
|
||||
f(f(f(f(f(f(static_cast<X&&>(x)))))))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
struct iterate_t<n, when<(n >= 12) && (n < 24)>> {
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return iterate_t<n - 12>{}(f,
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
static_cast<X&&>(x)
|
||||
))))))))))))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
struct iterate_t<n, when<(n >= 24) && (n < 48)>> {
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return iterate_t<n - 24>{}(f,
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
static_cast<X&&>(x)
|
||||
))))))))))))
|
||||
))))))))))))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
struct iterate_t<n, when<(n >= 48)>> {
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return iterate_t<n - 48>{}(f,
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
f(f(f(f(f(f(f(f(f(f(f(f(
|
||||
static_cast<X&&>(x)
|
||||
))))))))))))
|
||||
))))))))))))
|
||||
))))))))))))
|
||||
))))))))))))
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
struct make_iterate_t {
|
||||
template <typename F>
|
||||
constexpr decltype(auto) operator()(F&& f) const
|
||||
{ return hana::partial(iterate_t<n>{}, static_cast<F&&>(f)); }
|
||||
|
||||
template <typename F, typename X>
|
||||
constexpr decltype(auto) operator()(F&& f, X&& x) const {
|
||||
return iterate_t<n>{}(static_cast<F&&>(f),
|
||||
static_cast<X&&>(x));
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t n>
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_iterate_t<n> iterate{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_ITERATE_HPP
|
@ -0,0 +1,114 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::lockstep`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_LOCKSTEP_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_LOCKSTEP_HPP
|
||||
|
||||
#include <boost/hana/basic_tuple.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Invoke a function with the result of invoking other functions on its
|
||||
//! arguments, in lockstep.
|
||||
//!
|
||||
//! Specifically, `lockstep(f)(g1, ..., gN)` is a function such that
|
||||
//! @code
|
||||
//! lockstep(f)(g1, ..., gN)(x1, ..., xN) == f(g1(x1), ..., gN(xN))
|
||||
//! @endcode
|
||||
//!
|
||||
//! Since each `g` is invoked on its corresponding argument in lockstep,
|
||||
//! the number of arguments must match the number of `g`s.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/functional/lockstep.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto lockstep = [](auto&& f, auto&& ...g) {
|
||||
return [perfect-capture](auto&& ...x) -> decltype(auto) {
|
||||
return forwarded(f)(forwarded(g)(forwarded(x))...);
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename Indices, typename F, typename ...G>
|
||||
struct lockstep_t;
|
||||
|
||||
template <typename F>
|
||||
struct pre_lockstep_t;
|
||||
|
||||
struct make_pre_lockstep_t {
|
||||
struct secret { };
|
||||
template <typename F>
|
||||
constexpr pre_lockstep_t<typename detail::decay<F>::type> operator()(F&& f) const {
|
||||
return {static_cast<F&&>(f)};
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t ...n, typename F, typename ...G>
|
||||
struct lockstep_t<std::index_sequence<n...>, F, G...> {
|
||||
template <typename ...T>
|
||||
constexpr lockstep_t(make_pre_lockstep_t::secret, T&& ...t)
|
||||
: storage_{static_cast<T&&>(t)...}
|
||||
{ }
|
||||
|
||||
basic_tuple<F, G...> storage_;
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) const& {
|
||||
return hana::at_c<0>(storage_)(
|
||||
hana::at_c<n+1>(storage_)(static_cast<X&&>(x))...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) & {
|
||||
return hana::at_c<0>(storage_)(
|
||||
hana::at_c<n+1>(storage_)(static_cast<X&&>(x))...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) && {
|
||||
return static_cast<F&&>(hana::at_c<0>(storage_))(
|
||||
static_cast<G&&>(hana::at_c<n+1>(storage_))(static_cast<X&&>(x))...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct pre_lockstep_t {
|
||||
F f;
|
||||
|
||||
template <typename ...G>
|
||||
constexpr lockstep_t<std::make_index_sequence<sizeof...(G)>, F,
|
||||
typename detail::decay<G>::type...>
|
||||
operator()(G&& ...g) const& {
|
||||
return {make_pre_lockstep_t::secret{}, this->f, static_cast<G&&>(g)...};
|
||||
}
|
||||
|
||||
template <typename ...G>
|
||||
constexpr lockstep_t<std::make_index_sequence<sizeof...(G)>, F,
|
||||
typename detail::decay<G>::type...>
|
||||
operator()(G&& ...g) && {
|
||||
return {make_pre_lockstep_t::secret{}, static_cast<F&&>(this->f),
|
||||
static_cast<G&&>(g)...};
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_pre_lockstep_t lockstep{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_LOCKSTEP_HPP
|
@ -0,0 +1,83 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::on`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_ON_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_ON_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/create.hpp>
|
||||
#include <boost/hana/functional/infix.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Invoke a function with the result of invoking another function on
|
||||
//! each argument.
|
||||
//!
|
||||
//! Specifically, `on(f, g)` is a function such that
|
||||
//! @code
|
||||
//! on(f, g)(x...) == f(g(x)...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! For convenience, `on` also supports infix application as provided
|
||||
//! by `infix`.
|
||||
//!
|
||||
//!
|
||||
//! @note
|
||||
//! `on` is associative, i.e. `on(f, on(g, h))` is equivalent to
|
||||
//! `on(on(f, g), h)`.
|
||||
//!
|
||||
//! @internal
|
||||
//! ### Proof of associativity
|
||||
//!
|
||||
//! @code
|
||||
//! on(f, on(g, h))(xs...) == f(on(g, h)(xs)...)
|
||||
//! == f(g(h(xs))...)
|
||||
//!
|
||||
//! on(on(f, g), h)(xs...) == on(f, g)(h(xs)...)
|
||||
//! == f(g(h(xs))...)
|
||||
//! @endcode
|
||||
//! @endinternal
|
||||
//!
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/on.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto on = infix([](auto&& f, auto&& g) {
|
||||
return [perfect-capture](auto&& ...x) -> decltype(auto) {
|
||||
return forwarded(f)(g(forwarded(x))...);
|
||||
};
|
||||
});
|
||||
#else
|
||||
template <typename F, typename G>
|
||||
struct on_t {
|
||||
F f; G g;
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) const& {
|
||||
return f(g(static_cast<X&&>(x))...);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) & {
|
||||
return f(g(static_cast<X&&>(x))...);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) && {
|
||||
return std::move(f)(g(static_cast<X&&>(x))...);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr auto on = infix(detail::create<on_t>{});
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_ON_HPP
|
@ -0,0 +1,88 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::overload`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_OVERLOAD_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_OVERLOAD_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Pick one of several functions to call based on overload resolution.
|
||||
//!
|
||||
//! Specifically, `overload(f1, f2, ..., fn)` is a function object such
|
||||
//! that
|
||||
//! @code
|
||||
//! overload(f1, f2, ..., fn)(x...) == fk(x...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! where `fk` is the function of `f1, ..., fn` that would be called if
|
||||
//! overload resolution was performed amongst that set of functions only.
|
||||
//! If more than one function `fk` would be picked by overload resolution,
|
||||
//! then the call is ambiguous.
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/overload.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto overload = [](auto&& f1, auto&& f2, ..., auto&& fn) {
|
||||
return [perfect-capture](auto&& ...x) -> decltype(auto) {
|
||||
return forwarded(fk)(forwarded(x)...);
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename F, typename ...G>
|
||||
struct overload_t
|
||||
: overload_t<F>::type
|
||||
, overload_t<G...>::type
|
||||
{
|
||||
using type = overload_t;
|
||||
using overload_t<F>::type::operator();
|
||||
using overload_t<G...>::type::operator();
|
||||
|
||||
template <typename F_, typename ...G_>
|
||||
constexpr explicit overload_t(F_&& f, G_&& ...g)
|
||||
: overload_t<F>::type(static_cast<F_&&>(f))
|
||||
, overload_t<G...>::type(static_cast<G_&&>(g)...)
|
||||
{ }
|
||||
};
|
||||
|
||||
template <typename F>
|
||||
struct overload_t<F> { using type = F; };
|
||||
|
||||
template <typename R, typename ...Args>
|
||||
struct overload_t<R(*)(Args...)> {
|
||||
using type = overload_t;
|
||||
R (*fptr_)(Args...);
|
||||
|
||||
explicit constexpr overload_t(R (*fp)(Args...))
|
||||
: fptr_(fp)
|
||||
{ }
|
||||
|
||||
constexpr R operator()(Args ...args) const
|
||||
{ return fptr_(static_cast<Args&&>(args)...); }
|
||||
};
|
||||
|
||||
struct make_overload_t {
|
||||
template <typename ...F,
|
||||
typename Overload = typename overload_t<
|
||||
typename detail::decay<F>::type...
|
||||
>::type
|
||||
>
|
||||
constexpr Overload operator()(F&& ...f) const {
|
||||
return Overload(static_cast<F&&>(f)...);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_overload_t overload{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_OVERLOAD_HPP
|
@ -0,0 +1,110 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::overload_linearly`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_OVERLOAD_LINEARLY_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_OVERLOAD_LINEARLY_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Call the first function that produces a valid call expression.
|
||||
//!
|
||||
//! Given functions `f1, ..., fn`, `overload_linearly(f1, ..., fn)` is
|
||||
//! a new function that calls the first `fk` producing a valid call
|
||||
//! expression with the given arguments. Specifically,
|
||||
//! @code
|
||||
//! overload_linearly(f1, ..., fn)(args...) == fk(args...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! where `fk` is the _first_ function such that `fk(args...)` is a valid
|
||||
//! expression.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/functional/overload_linearly.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto overload_linearly = [](auto&& f1, auto&& f2, ..., auto&& fn) {
|
||||
return [perfect-capture](auto&& ...x) -> decltype(auto) {
|
||||
return forwarded(fk)(forwarded(x)...);
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename F, typename G>
|
||||
struct overload_linearly_t {
|
||||
F f;
|
||||
G g;
|
||||
|
||||
private:
|
||||
template <typename ...Args, typename =
|
||||
decltype(std::declval<F const&>()(std::declval<Args>()...))>
|
||||
constexpr F const& which(int) const& { return f; }
|
||||
|
||||
template <typename ...Args, typename =
|
||||
decltype(std::declval<F&>()(std::declval<Args>()...))>
|
||||
constexpr F& which(int) & { return f; }
|
||||
|
||||
template <typename ...Args, typename =
|
||||
decltype(std::declval<F&&>()(std::declval<Args>()...))>
|
||||
constexpr F which(int) && { return static_cast<F&&>(f); }
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr G const& which(long) const& { return g; }
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr G& which(long) & { return g; }
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr G which(long) && { return static_cast<G&&>(g); }
|
||||
|
||||
public:
|
||||
template <typename ...Args>
|
||||
constexpr decltype(auto) operator()(Args&& ...args) const&
|
||||
{ return which<Args...>(int{})(static_cast<Args&&>(args)...); }
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr decltype(auto) operator()(Args&& ...args) &
|
||||
{ return which<Args...>(int{})(static_cast<Args&&>(args)...); }
|
||||
|
||||
template <typename ...Args>
|
||||
constexpr decltype(auto) operator()(Args&& ...args) &&
|
||||
{ return which<Args...>(int{})(static_cast<Args&&>(args)...); }
|
||||
};
|
||||
|
||||
struct make_overload_linearly_t {
|
||||
template <typename F, typename G>
|
||||
constexpr overload_linearly_t<
|
||||
typename detail::decay<F>::type,
|
||||
typename detail::decay<G>::type
|
||||
> operator()(F&& f, G&& g) const {
|
||||
return {static_cast<F&&>(f), static_cast<G&&>(g)};
|
||||
}
|
||||
|
||||
template <typename F, typename G, typename ...H>
|
||||
constexpr decltype(auto) operator()(F&& f, G&& g, H&& ...h) const {
|
||||
return (*this)(static_cast<F&&>(f),
|
||||
(*this)(static_cast<G&&>(g), static_cast<H&&>(h)...));
|
||||
}
|
||||
|
||||
template <typename F>
|
||||
constexpr typename detail::decay<F>::type operator()(F&& f) const {
|
||||
return static_cast<F&&>(f);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_overload_linearly_t overload_linearly{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_OVERLOAD_LINEARLY_HPP
|
@ -0,0 +1,105 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::partial`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_PARTIAL_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_PARTIAL_HPP
|
||||
|
||||
#include <boost/hana/basic_tuple.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Partially apply a function to some arguments.
|
||||
//!
|
||||
//! Given a function `f` and some arguments, `partial` returns a new
|
||||
//! function corresponding to the partially applied function `f`. This
|
||||
//! allows providing some arguments to a function and letting the rest
|
||||
//! of the arguments be provided later. Specifically, `partial(f, x...)`
|
||||
//! is a function such that
|
||||
//! @code
|
||||
//! partial(f, x...)(y...) == f(x..., y...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! @note
|
||||
//! The arity of `f` must match the total number of arguments passed to
|
||||
//! it, i.e. `sizeof...(x) + sizeof...(y)`.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/functional/partial.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto partial = [](auto&& f, auto&& ...x) {
|
||||
return [perfect-capture](auto&& ...y) -> decltype(auto) {
|
||||
return forwarded(f)(forwarded(x)..., forwarded(y)...);
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename Indices, typename F, typename ...X>
|
||||
struct partial_t;
|
||||
|
||||
struct make_partial_t {
|
||||
struct secret { };
|
||||
template <typename F, typename ...X>
|
||||
constexpr partial_t<
|
||||
std::make_index_sequence<sizeof...(X)>,
|
||||
typename detail::decay<F>::type,
|
||||
typename detail::decay<X>::type...
|
||||
>
|
||||
operator()(F&& f, X&& ...x) const {
|
||||
return {secret{}, static_cast<F&&>(f), static_cast<X&&>(x)...};
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t ...n, typename F, typename ...X>
|
||||
struct partial_t<std::index_sequence<n...>, F, X...> {
|
||||
partial_t() = default;
|
||||
|
||||
template <typename ...T>
|
||||
constexpr partial_t(make_partial_t::secret, T&& ...t)
|
||||
: storage_{static_cast<T&&>(t)...}
|
||||
{ }
|
||||
|
||||
basic_tuple<F, X...> storage_;
|
||||
|
||||
template <typename ...Y>
|
||||
constexpr decltype(auto) operator()(Y&& ...y) const& {
|
||||
return hana::at_c<0>(storage_)(
|
||||
hana::at_c<n+1>(storage_)...,
|
||||
static_cast<Y&&>(y)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...Y>
|
||||
constexpr decltype(auto) operator()(Y&& ...y) & {
|
||||
return hana::at_c<0>(storage_)(
|
||||
hana::at_c<n+1>(storage_)...,
|
||||
static_cast<Y&&>(y)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...Y>
|
||||
constexpr decltype(auto) operator()(Y&& ...y) && {
|
||||
return static_cast<F&&>(hana::at_c<0>(storage_))(
|
||||
static_cast<X&&>(hana::at_c<n+1>(storage_))...,
|
||||
static_cast<Y&&>(y)...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_partial_t partial{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_PARTIAL_HPP
|
@ -0,0 +1,263 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::_`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_PLACEHOLDER_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_PLACEHOLDER_HPP
|
||||
|
||||
#include <boost/hana/basic_tuple.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/create.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Create simple functions representing C++ operators inline.
|
||||
//!
|
||||
//! Specifically, `_` is an object used as a placeholder to build
|
||||
//! function objects representing calls to C++ operators. It works
|
||||
//! by overloading the operators between `_` and any object so that
|
||||
//! they return a function object which actually calls the corresponding
|
||||
//! operator on its argument(s). Hence, for any supported operator `@`:
|
||||
//! @code
|
||||
//! (_ @ _)(x, y) == x @ y
|
||||
//! @endcode
|
||||
//!
|
||||
//! Operators may also be partially applied to one argument inline:
|
||||
//! @code
|
||||
//! (x @ _)(y) == x @ y
|
||||
//! (_ @ y)(x) == x @ y
|
||||
//! @endcode
|
||||
//!
|
||||
//! When invoked with more arguments than required, functions created with
|
||||
//! `_` will discard the superfluous instead of triggering an error:
|
||||
//! @code
|
||||
//! (_ @ _)(x, y, z...) == x @ y
|
||||
//! @endcode
|
||||
//!
|
||||
//! This makes functions created with `_` easier to use in higher-order
|
||||
//! algorithms, which sometime provide more information than necessary
|
||||
//! to their callbacks.
|
||||
//!
|
||||
//! ### Supported operators
|
||||
//! - Arithmetic: binary `+`, binary `-`, `/`, `*`, `%`, unary `+`, unary `-`
|
||||
//! - Bitwise: `~`, `&`, `|`, `^`, `<<`, `>>`
|
||||
//! - Comparison: `==`, `!=`, `<`, `<=`, `>`, `>=`
|
||||
//! - %Logical: `||`, `&&`, `!`
|
||||
//! - Member access: `*` (dereference), `[]` (array subscript)
|
||||
//! - Other: `()` (function call)
|
||||
//!
|
||||
//! More complex functionality like the ability to compose placeholders
|
||||
//! into larger function objects inline are not supported. This is on
|
||||
//! purpose; you should either use C++14 generic lambdas or a library
|
||||
//! like [Boost.Phoenix][] if you need bigger guns. The goal here is
|
||||
//! to save you a couple of characters in simple situations.
|
||||
//!
|
||||
//! ### Example
|
||||
//! @include example/functional/placeholder.cpp
|
||||
//!
|
||||
//! [Boost.Phoenix]: http://www.boost.org/doc/libs/release/libs/phoenix/doc/html/index.html
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr unspecified _{};
|
||||
#else
|
||||
namespace placeholder_detail {
|
||||
template <typename I>
|
||||
struct subscript {
|
||||
I i;
|
||||
|
||||
template <typename Xs, typename ...Z>
|
||||
constexpr auto operator()(Xs&& xs, Z const& ...) const&
|
||||
-> decltype(static_cast<Xs&&>(xs)[i])
|
||||
{ return static_cast<Xs&&>(xs)[i]; }
|
||||
|
||||
template <typename Xs, typename ...Z>
|
||||
constexpr auto operator()(Xs&& xs, Z const& ...) &
|
||||
-> decltype(static_cast<Xs&&>(xs)[i])
|
||||
{ return static_cast<Xs&&>(xs)[i]; }
|
||||
|
||||
template <typename Xs, typename ...Z>
|
||||
constexpr auto operator()(Xs&& xs, Z const& ...) &&
|
||||
-> decltype(static_cast<Xs&&>(xs)[std::declval<I>()])
|
||||
{ return static_cast<Xs&&>(xs)[std::move(i)]; }
|
||||
};
|
||||
|
||||
template <typename F, typename Xs, std::size_t ...i>
|
||||
constexpr decltype(auto) invoke_impl(F&& f, Xs&& xs, std::index_sequence<i...>) {
|
||||
return static_cast<F&&>(f)(hana::at_c<i>(static_cast<Xs&&>(xs).storage_)...);
|
||||
}
|
||||
|
||||
template <typename ...X>
|
||||
struct invoke;
|
||||
|
||||
struct placeholder {
|
||||
struct secret { };
|
||||
|
||||
template <typename X>
|
||||
constexpr decltype(auto) operator[](X&& x) const
|
||||
{ return detail::create<subscript>{}(static_cast<X&&>(x)); }
|
||||
|
||||
template <typename ...X>
|
||||
constexpr invoke<typename detail::decay<X>::type...>
|
||||
operator()(X&& ...x) const {
|
||||
return {secret{}, static_cast<X&&>(x)...};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename ...X>
|
||||
struct invoke {
|
||||
template <typename ...Y>
|
||||
constexpr invoke(placeholder::secret, Y&& ...y)
|
||||
: storage_{static_cast<Y&&>(y)...}
|
||||
{ }
|
||||
|
||||
basic_tuple<X...> storage_;
|
||||
|
||||
template <typename F, typename ...Z>
|
||||
constexpr auto operator()(F&& f, Z const& ...) const& -> decltype(
|
||||
static_cast<F&&>(f)(std::declval<X const&>()...)
|
||||
) {
|
||||
return invoke_impl(static_cast<F&&>(f), *this,
|
||||
std::make_index_sequence<sizeof...(X)>{});
|
||||
}
|
||||
|
||||
template <typename F, typename ...Z>
|
||||
constexpr auto operator()(F&& f, Z const& ...) & -> decltype(
|
||||
static_cast<F&&>(f)(std::declval<X&>()...)
|
||||
) {
|
||||
return invoke_impl(static_cast<F&&>(f), *this,
|
||||
std::make_index_sequence<sizeof...(X)>{});
|
||||
}
|
||||
|
||||
template <typename F, typename ...Z>
|
||||
constexpr auto operator()(F&& f, Z const& ...) && -> decltype(
|
||||
static_cast<F&&>(f)(std::declval<X&&>()...)
|
||||
) {
|
||||
return invoke_impl(static_cast<F&&>(f), static_cast<invoke&&>(*this),
|
||||
std::make_index_sequence<sizeof...(X)>{});
|
||||
}
|
||||
};
|
||||
|
||||
#define BOOST_HANA_PLACEHOLDER_BINARY_OP(op, op_name) \
|
||||
template <typename X> \
|
||||
struct op_name ## _left { \
|
||||
X x; \
|
||||
\
|
||||
template <typename Y, typename ...Z> \
|
||||
constexpr auto operator()(Y&& y, Z const& ...) const& -> decltype( \
|
||||
std::declval<X const&>() op static_cast<Y&&>(y)) \
|
||||
{ return x op static_cast<Y&&>(y); } \
|
||||
\
|
||||
template <typename Y, typename ...Z> \
|
||||
constexpr auto operator()(Y&& y, Z const& ...) & -> decltype( \
|
||||
std::declval<X&>() op static_cast<Y&&>(y)) \
|
||||
{ return x op static_cast<Y&&>(y); } \
|
||||
\
|
||||
template <typename Y, typename ...Z> \
|
||||
constexpr auto operator()(Y&& y, Z const& ...) && -> decltype( \
|
||||
std::declval<X>() op static_cast<Y&&>(y)) \
|
||||
{ return std::move(x) op static_cast<Y&&>(y); } \
|
||||
}; \
|
||||
\
|
||||
template <typename Y> \
|
||||
struct op_name ## _right { \
|
||||
Y y; \
|
||||
\
|
||||
template <typename X, typename ...Z> \
|
||||
constexpr auto operator()(X&& x, Z const& ...) const& -> decltype( \
|
||||
static_cast<X&&>(x) op std::declval<Y const&>()) \
|
||||
{ return static_cast<X&&>(x) op y; } \
|
||||
\
|
||||
template <typename X, typename ...Z> \
|
||||
constexpr auto operator()(X&& x, Z const& ...) & -> decltype( \
|
||||
static_cast<X&&>(x) op std::declval<Y&>()) \
|
||||
{ return static_cast<X&&>(x) op y; } \
|
||||
\
|
||||
template <typename X, typename ...Z> \
|
||||
constexpr auto operator()(X&& x, Z const& ...) && -> decltype( \
|
||||
static_cast<X&&>(x) op std::declval<Y>()) \
|
||||
{ return static_cast<X&&>(x) op std::move(y); } \
|
||||
}; \
|
||||
\
|
||||
struct op_name { \
|
||||
template <typename X, typename Y, typename ...Z> \
|
||||
constexpr auto operator()(X&& x, Y&& y, Z const& ...) const -> decltype(\
|
||||
static_cast<X&&>(x) op static_cast<Y&&>(y)) \
|
||||
{ return static_cast<X&&>(x) op static_cast<Y&&>(y); } \
|
||||
}; \
|
||||
\
|
||||
template <typename X> \
|
||||
constexpr decltype(auto) operator op (X&& x, placeholder) \
|
||||
{ return detail::create<op_name ## _left>{}(static_cast<X&&>(x)); } \
|
||||
\
|
||||
template <typename Y> \
|
||||
constexpr decltype(auto) operator op (placeholder, Y&& y) \
|
||||
{ return detail::create<op_name ## _right>{}(static_cast<Y&&>(y)); } \
|
||||
\
|
||||
inline constexpr decltype(auto) operator op (placeholder, placeholder) \
|
||||
{ return op_name{}; } \
|
||||
/**/
|
||||
|
||||
#define BOOST_HANA_PLACEHOLDER_UNARY_OP(op, op_name) \
|
||||
struct op_name { \
|
||||
template <typename X, typename ...Z> \
|
||||
constexpr auto operator()(X&& x, Z const& ...) const \
|
||||
-> decltype(op static_cast<X&&>(x)) \
|
||||
{ return op static_cast<X&&>(x); } \
|
||||
}; \
|
||||
\
|
||||
inline constexpr decltype(auto) operator op (placeholder) \
|
||||
{ return op_name{}; } \
|
||||
/**/
|
||||
// Arithmetic
|
||||
BOOST_HANA_PLACEHOLDER_UNARY_OP(+, unary_plus)
|
||||
BOOST_HANA_PLACEHOLDER_UNARY_OP(-, unary_minus)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(+, plus)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(-, minus)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(*, times)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(/, divide)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(%, modulo)
|
||||
|
||||
// Bitwise
|
||||
BOOST_HANA_PLACEHOLDER_UNARY_OP(~, bitwise_not)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(&, bitwise_and)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(|, bitwise_or)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(^, bitwise_xor)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(<<, left_shift)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(>>, right_shift)
|
||||
|
||||
// Comparison
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(==, equal)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(!=, not_equal)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(<, less)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(<=, less_equal)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(>, greater)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(>=, greater_equal)
|
||||
|
||||
// Logical
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(||, logical_or)
|
||||
BOOST_HANA_PLACEHOLDER_BINARY_OP(&&, logical_and)
|
||||
BOOST_HANA_PLACEHOLDER_UNARY_OP(!, logical_not)
|
||||
|
||||
// Member access (array subscript is a member function)
|
||||
BOOST_HANA_PLACEHOLDER_UNARY_OP(*, dereference)
|
||||
|
||||
// Other (function call is a member function)
|
||||
|
||||
#undef BOOST_HANA_PREFIX_PLACEHOLDER_OP
|
||||
#undef BOOST_HANA_BINARY_PLACEHOLDER_OP
|
||||
} // end namespace placeholder_detail
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr placeholder_detail::placeholder _{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_PLACEHOLDER_HPP
|
@ -0,0 +1,103 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::reverse_partial`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUNCTIONAL_REVERSE_PARTIAL_HPP
|
||||
#define BOOST_HANA_FUNCTIONAL_REVERSE_PARTIAL_HPP
|
||||
|
||||
#include <boost/hana/basic_tuple.hpp>
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! @ingroup group-functional
|
||||
//! Partially apply a function to some arguments.
|
||||
//!
|
||||
//! Given a function `f` and some arguments, `reverse_partial` returns a
|
||||
//! new function corresponding to `f` whose last arguments are partially
|
||||
//! applied. Specifically, `reverse_partial(f, x...)` is a function such
|
||||
//! that
|
||||
//! @code
|
||||
//! reverse_partial(f, x...)(y...) == f(y..., x...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! @note
|
||||
//! The arity of `f` must match the total number of arguments passed to
|
||||
//! it, i.e. `sizeof...(x) + sizeof...(y)`.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/functional/reverse_partial.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto reverse_partial = [](auto&& f, auto&& ...x) {
|
||||
return [perfect-capture](auto&& ...y) -> decltype(auto) {
|
||||
return forwarded(f)(forwarded(y)..., forwarded(x)...);
|
||||
};
|
||||
};
|
||||
#else
|
||||
template <typename Indices, typename F, typename ...X>
|
||||
struct reverse_partial_t;
|
||||
|
||||
struct make_reverse_partial_t {
|
||||
struct secret { };
|
||||
template <typename F, typename ...X>
|
||||
constexpr reverse_partial_t<
|
||||
std::make_index_sequence<sizeof...(X)>,
|
||||
typename detail::decay<F>::type,
|
||||
typename detail::decay<X>::type...
|
||||
> operator()(F&& f, X&& ...x) const {
|
||||
return {secret{}, static_cast<F&&>(f), static_cast<X&&>(x)...};
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t ...n, typename F, typename ...X>
|
||||
struct reverse_partial_t<std::index_sequence<n...>, F, X...> {
|
||||
reverse_partial_t() = default;
|
||||
|
||||
template <typename ...T>
|
||||
constexpr reverse_partial_t(make_reverse_partial_t::secret, T&& ...t)
|
||||
: storage_{static_cast<T&&>(t)...}
|
||||
{ }
|
||||
|
||||
basic_tuple<F, X...> storage_;
|
||||
|
||||
template <typename ...Y>
|
||||
constexpr decltype(auto) operator()(Y&& ...y) const& {
|
||||
return hana::at_c<0>(storage_)(
|
||||
static_cast<Y&&>(y)...,
|
||||
hana::at_c<n+1>(storage_)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...Y>
|
||||
constexpr decltype(auto) operator()(Y&& ...y) & {
|
||||
return hana::at_c<0>(storage_)(
|
||||
static_cast<Y&&>(y)...,
|
||||
hana::at_c<n+1>(storage_)...
|
||||
);
|
||||
}
|
||||
|
||||
template <typename ...Y>
|
||||
constexpr decltype(auto) operator()(Y&& ...y) && {
|
||||
return static_cast<F&&>(hana::at_c<0>(storage_))(
|
||||
static_cast<Y&&>(y)...,
|
||||
static_cast<X&&>(hana::at_c<n+1>(storage_))...
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr make_reverse_partial_t reverse_partial{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUNCTIONAL_REVERSE_PARTIAL_HPP
|
47
_deps/boost-src/libs/hana/include/boost/hana/fuse.hpp
Normal file
47
_deps/boost-src/libs/hana/include/boost/hana/fuse.hpp
Normal file
@ -0,0 +1,47 @@
|
||||
/*!
|
||||
@file
|
||||
Defines `boost::hana::fuse`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_FUSE_HPP
|
||||
#define BOOST_HANA_FUSE_HPP
|
||||
|
||||
#include <boost/hana/fwd/fuse.hpp>
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/detail/decay.hpp>
|
||||
#include <boost/hana/unpack.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
namespace detail {
|
||||
template <typename F>
|
||||
struct fused {
|
||||
F f;
|
||||
template <typename Xs>
|
||||
constexpr decltype(auto) operator()(Xs&& xs) const&
|
||||
{ return hana::unpack(static_cast<Xs&&>(xs), f); }
|
||||
|
||||
template <typename Xs>
|
||||
constexpr decltype(auto) operator()(Xs&& xs) &
|
||||
{ return hana::unpack(static_cast<Xs&&>(xs), f); }
|
||||
|
||||
template <typename Xs>
|
||||
constexpr decltype(auto) operator()(Xs&& xs) &&
|
||||
{ return hana::unpack(static_cast<Xs&&>(xs), static_cast<F&&>(f)); }
|
||||
};
|
||||
}
|
||||
|
||||
//! @cond
|
||||
template <typename F>
|
||||
constexpr auto fuse_t::operator()(F&& f) const {
|
||||
return detail::fused<typename detail::decay<F>::type>{static_cast<F&&>(f)};
|
||||
}
|
||||
//! @endcond
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FUSE_HPP
|
@ -0,0 +1,50 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::accessors`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ACCESSORS_HPP
|
||||
#define BOOST_HANA_FWD_ACCESSORS_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! Returns a `Sequence` of pairs representing the accessors of the
|
||||
//! data structure.
|
||||
//! @ingroup group-Struct
|
||||
//!
|
||||
//! Given a `Struct` `S`, `accessors<S>()` is a `Sequence` of `Product`s
|
||||
//! where the first element of each pair is the "name" of a member of
|
||||
//! the `Struct`, and the second element of each pair is a function that
|
||||
//! can be used to access that member when given an object of the proper
|
||||
//! data type. As described in the global documentation for `Struct`, the
|
||||
//! accessor functions in this sequence must be move-independent.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/accessors.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename S>
|
||||
constexpr auto accessors = []() {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename S, typename = void>
|
||||
struct accessors_impl : accessors_impl<S, when<true>> { };
|
||||
|
||||
template <typename S>
|
||||
struct accessors_t;
|
||||
|
||||
template <typename S>
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr accessors_t<S> accessors{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_ACCESSORS_HPP
|
@ -0,0 +1,48 @@
|
||||
/*!
|
||||
@file
|
||||
Documents the `BOOST_HANA_ADAPT_ADT` macro.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ADAPT_ADT_HPP
|
||||
#define BOOST_HANA_FWD_ADAPT_ADT_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
// Note:
|
||||
// The weird definition as a variable seems to exploit a glitch in Doxygen
|
||||
// which makes the macro appear in the related objects of Struct (as we
|
||||
// want it to).
|
||||
|
||||
//! Defines a model of `Struct` with the given accessors.
|
||||
//! @ingroup group-Struct
|
||||
//!
|
||||
//! Using this macro at _global scope_ will define a model of the `Struct`
|
||||
//! concept for the given type. This can be used to easily adapt existing
|
||||
//! user-defined types in a ad-hoc manner. Unlike `BOOST_HANA_ADAPT_STRUCT`,
|
||||
//! this macro requires specifying the way to retrieve each member by
|
||||
//! providing a function that does the extraction.
|
||||
//!
|
||||
//! @note
|
||||
//! This macro only works if the tag of the user-defined type `T` is `T`
|
||||
//! itself. This is the case unless you specifically asked for something
|
||||
//! different; see `tag_of`'s documentation.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/adapt_adt.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
auto BOOST_HANA_ADAPT_ADT(...) = ;
|
||||
#define BOOST_HANA_ADAPT_ADT(Name, ...) see documentation
|
||||
#else
|
||||
// defined in <boost/hana/adapt_adt.hpp>
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_ADAPT_ADT_HPP
|
@ -0,0 +1,48 @@
|
||||
/*!
|
||||
@file
|
||||
Documents the `BOOST_HANA_ADAPT_STRUCT` macro.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ADAPT_STRUCT_HPP
|
||||
#define BOOST_HANA_FWD_ADAPT_STRUCT_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
// Note:
|
||||
// The weird definition as a variable seems to exploit a glitch in Doxygen
|
||||
// which makes the macro appear in the related objects of Struct (as we
|
||||
// want it to).
|
||||
|
||||
//! Defines a model of `Struct` with the given members.
|
||||
//! @ingroup group-Struct
|
||||
//!
|
||||
//! Using this macro at _global scope_ will define a model of the `Struct`
|
||||
//! concept for the given type. This can be used to easily adapt existing
|
||||
//! user-defined types in a ad-hoc manner. Unlike the
|
||||
//! `BOOST_HANA_DEFINE_STRUCT` macro, this macro does not
|
||||
//! require the types of the members to be specified.
|
||||
//!
|
||||
//! @note
|
||||
//! This macro only works if the tag of the user-defined type `T` is `T`
|
||||
//! itself. This is the case unless you specifically asked for something
|
||||
//! different; see `tag_of`'s documentation.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/adapt_struct.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
auto BOOST_HANA_ADAPT_STRUCT(...) = ;
|
||||
#define BOOST_HANA_ADAPT_STRUCT(Name, ...) see documentation
|
||||
#else
|
||||
// defined in <boost/hana/adapt_struct.hpp>
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_ADAPT_STRUCT_HPP
|
64
_deps/boost-src/libs/hana/include/boost/hana/fwd/adjust.hpp
Normal file
64
_deps/boost-src/libs/hana/include/boost/hana/fwd/adjust.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::adjust`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ADJUST_HPP
|
||||
#define BOOST_HANA_FWD_ADJUST_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! Apply a function on all the elements of a structure that compare
|
||||
//! equal to some value.
|
||||
//! @ingroup group-Functor
|
||||
//!
|
||||
//!
|
||||
//! Signature
|
||||
//! ---------
|
||||
//! Given `F` a Functor and `U` a type that can be compared with `T`'s,
|
||||
//! the signature is
|
||||
//! \f$
|
||||
//! \mathtt{adjust} : F(T) \times U \times (T \to T) \to F(T)
|
||||
//! \f$
|
||||
//!
|
||||
//! @param xs
|
||||
//! The structure to adjust with `f`.
|
||||
//!
|
||||
//! @param value
|
||||
//! An object that is compared with each element `x` of the structure.
|
||||
//! Elements of the structure that compare equal to `value` are adjusted
|
||||
//! with the `f` function.
|
||||
//!
|
||||
//! @param f
|
||||
//! A function called as `f(x)` on the element(s) of the structure that
|
||||
//! compare equal to `value`.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/adjust.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto adjust = [](auto&& xs, auto&& value, auto&& f) {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename Xs, typename = void>
|
||||
struct adjust_impl : adjust_impl<Xs, when<true>> { };
|
||||
|
||||
struct adjust_t {
|
||||
template <typename Xs, typename Value, typename F>
|
||||
constexpr auto operator()(Xs&& xs, Value&& value, F&& f) const;
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr adjust_t adjust{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_ADJUST_HPP
|
@ -0,0 +1,69 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::adjust_if`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ADJUST_IF_HPP
|
||||
#define BOOST_HANA_FWD_ADJUST_IF_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! Apply a function on all the elements of a structure satisfying a predicate.
|
||||
//! @ingroup group-Functor
|
||||
//!
|
||||
//! Given a Functor, a predicate `pred` and a function `f`, `adjust_if`
|
||||
//! will _adjust_ the elements of the Functor that satisfy the predicate
|
||||
//! with the function `f`. In other words, `adjust_if` will return a new
|
||||
//! Functor equal to the original one, except that the elements satisfying
|
||||
//! the predicate will be transformed with the given function. Elements
|
||||
//! for which the predicate is not satisfied are left untouched, and they
|
||||
//! are kept as-is in the resulting Functor.
|
||||
//!
|
||||
//!
|
||||
//! Signature
|
||||
//! ---------
|
||||
//! 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)
|
||||
//! \f$
|
||||
//!
|
||||
//! @param xs
|
||||
//! The structure to adjust with `f`.
|
||||
//!
|
||||
//! @param pred
|
||||
//! A function called as `pred(x)` for each element of the Functor,
|
||||
//! and returning whether `f` should be applied on that element.
|
||||
//!
|
||||
//! @param f
|
||||
//! A function called as `f(x)` on the element(s) of the Functor that
|
||||
//! satisfy the predicate.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/adjust_if.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto adjust_if = [](auto&& xs, auto const& pred, auto const& f) {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename Xs, typename = void>
|
||||
struct adjust_if_impl : adjust_if_impl<Xs, when<true>> { };
|
||||
|
||||
struct adjust_if_t {
|
||||
template <typename Xs, typename Pred, typename F>
|
||||
constexpr auto operator()(Xs&& xs, Pred const& pred, F const& f) const;
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr adjust_if_t adjust_if{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_ADJUST_IF_HPP
|
46
_deps/boost-src/libs/hana/include/boost/hana/fwd/all.hpp
Normal file
46
_deps/boost-src/libs/hana/include/boost/hana/fwd/all.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::all`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ALL_HPP
|
||||
#define BOOST_HANA_FWD_ALL_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! Returns whether all the keys of the structure are true-valued.
|
||||
//! @ingroup group-Searchable
|
||||
//!
|
||||
//! The keys of the structure must be `Logical`s. If the structure is not
|
||||
//! finite, a false-valued key must appear at a finite "index" in order
|
||||
//! for this method to finish.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/all.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto all = [](auto&& xs) {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename S, typename = void>
|
||||
struct all_impl : all_impl<S, when<true>> { };
|
||||
|
||||
struct all_t {
|
||||
template <typename Xs>
|
||||
constexpr auto operator()(Xs&& xs) const;
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr all_t all{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_ALL_HPP
|
54
_deps/boost-src/libs/hana/include/boost/hana/fwd/all_of.hpp
Normal file
54
_deps/boost-src/libs/hana/include/boost/hana/fwd/all_of.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::all_of`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ALL_OF_HPP
|
||||
#define BOOST_HANA_FWD_ALL_OF_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! Returns whether all the keys of the structure satisfy the `predicate`.
|
||||
//! @ingroup group-Searchable
|
||||
//!
|
||||
//! If the structure is not finite, `predicate` has to return a false-
|
||||
//! valued `Logical` after looking at a finite number of keys for this
|
||||
//! method to finish.
|
||||
//!
|
||||
//!
|
||||
//! @param xs
|
||||
//! The structure to search.
|
||||
//!
|
||||
//! @param predicate
|
||||
//! A function called as `predicate(k)`, where `k` is a key of the
|
||||
//! structure, and returning a `Logical`.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/all_of.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto all_of = [](auto&& xs, auto&& predicate) {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename S, typename = void>
|
||||
struct all_of_impl : all_of_impl<S, when<true>> { };
|
||||
|
||||
struct all_of_t {
|
||||
template <typename Xs, typename Pred>
|
||||
constexpr auto operator()(Xs&& xs, Pred&& pred) const;
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr all_of_t all_of{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_ALL_OF_HPP
|
53
_deps/boost-src/libs/hana/include/boost/hana/fwd/and.hpp
Normal file
53
_deps/boost-src/libs/hana/include/boost/hana/fwd/and.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::and_`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_AND_HPP
|
||||
#define BOOST_HANA_FWD_AND_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! Return whether all the arguments are true-valued.
|
||||
//! @ingroup group-Logical
|
||||
//!
|
||||
//! `and_` can be called with one argument or more. When called with
|
||||
//! two arguments, `and_` uses tag-dispatching to find the right
|
||||
//! implementation. Otherwise,
|
||||
//! @code
|
||||
//! and_(x) == x
|
||||
//! and_(x, y, ...z) == and_(and_(x, y), z...)
|
||||
//! @endcode
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/and.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto and_ = [](auto&& x, auto&& ...y) -> decltype(auto) {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename L, typename = void>
|
||||
struct and_impl : and_impl<L, when<true>> { };
|
||||
|
||||
struct and_t {
|
||||
template <typename X, typename Y>
|
||||
constexpr decltype(auto) operator()(X&& x, Y&& y) const;
|
||||
|
||||
template <typename X, typename ...Y>
|
||||
constexpr decltype(auto) operator()(X&& x, Y&& ...y) const;
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr and_t and_{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_AND_HPP
|
46
_deps/boost-src/libs/hana/include/boost/hana/fwd/any.hpp
Normal file
46
_deps/boost-src/libs/hana/include/boost/hana/fwd/any.hpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::any`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ANY_HPP
|
||||
#define BOOST_HANA_FWD_ANY_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! Returns whether any key of the structure is true-valued.
|
||||
//! @ingroup group-Searchable
|
||||
//!
|
||||
//! The keys of the structure must be `Logical`s. If the structure is not
|
||||
//! finite, a true-valued key must appear at a finite "index" in order for
|
||||
//! this method to finish.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/any.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto any = [](auto&& xs) {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename S, typename = void>
|
||||
struct any_impl : any_impl<S, when<true>> { };
|
||||
|
||||
struct any_t {
|
||||
template <typename Xs>
|
||||
constexpr auto operator()(Xs&& xs) const;
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr any_t any{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_ANY_HPP
|
53
_deps/boost-src/libs/hana/include/boost/hana/fwd/any_of.hpp
Normal file
53
_deps/boost-src/libs/hana/include/boost/hana/fwd/any_of.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::any_of`.
|
||||
|
||||
Copyright Louis Dionne 2013-2022
|
||||
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_ANY_OF_HPP
|
||||
#define BOOST_HANA_FWD_ANY_OF_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
#include <boost/hana/core/when.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace hana {
|
||||
//! Returns whether any key of the structure satisfies the `predicate`.
|
||||
//! @ingroup group-Searchable
|
||||
//!
|
||||
//! If the structure is not finite, `predicate` has to be satisfied
|
||||
//! after looking at a finite number of keys for this method to finish.
|
||||
//!
|
||||
//!
|
||||
//! @param xs
|
||||
//! The structure to search.
|
||||
//!
|
||||
//! @param predicate
|
||||
//! A function called as `predicate(k)`, where `k` is a key of the
|
||||
//! structure, and returning a `Logical`.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/any_of.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
constexpr auto any_of = [](auto&& xs, auto&& predicate) {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename S, typename = void>
|
||||
struct any_of_impl : any_of_impl<S, when<true>> { };
|
||||
|
||||
struct any_of_t {
|
||||
template <typename Xs, typename Pred>
|
||||
constexpr auto operator()(Xs&& xs, Pred&& pred) const;
|
||||
};
|
||||
|
||||
BOOST_HANA_INLINE_VARIABLE constexpr any_of_t any_of{};
|
||||
#endif
|
||||
}} // end namespace boost::hana
|
||||
|
||||
#endif // !BOOST_HANA_FWD_ANY_OF_HPP
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user