Skip to content

Commit 6187d44

Browse files
committed
Merge develop into master for release 1.5.0
2 parents e53c547 + 1e1bedb commit 6187d44

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+454
-251
lines changed

doc/tutorial.hpp

+27-6
Original file line numberDiff line numberDiff line change
@@ -1703,7 +1703,7 @@ that type and cast it to `void`, for the same reason as we did for non-static
17031703
members.
17041704
17051705
1706-
@subsubsection tutorial-introspection-is_valid-typename Nested type names
1706+
@subsubsection tutorial-introspection-is_valid-nested-typename Nested type names
17071707
17081708
Checking for a nested type name is not hard, but it is slightly more
17091709
convoluted than the previous cases:
@@ -1716,7 +1716,7 @@ support types that can't be returned from functions, like array types or
17161716
incomplete types.
17171717
17181718
1719-
@subsubsection tutorial-introspection-is_valid-template Nested templates
1719+
@subsubsection tutorial-introspection-is_valid-nested-template Nested templates
17201720
17211721
Checking for a nested template name is similar to checking for a nested type
17221722
name, except we use the `template_<...>` variable template instead of
@@ -1725,6 +1725,21 @@ name, except we use the `template_<...>` variable template instead of
17251725
@snippet example/tutorial/introspection.cpp nested_template
17261726
17271727
1728+
@subsubsection tutorial-introspection-is_valid-template Template specializations
1729+
1730+
Checking whether a template specialization is valid can be done too, but we
1731+
now pass a `template_<...>` to `is_valid` instead of a `type<...>`, because
1732+
that's what we want to make the check on:
1733+
1734+
@snippet example/tutorial/introspection.cpp template_specialization
1735+
1736+
@note
1737+
Doing this will not cause the template to be instantiated. Hence, it will only
1738+
check whether the given template can be mentioned with the provided template
1739+
arguments, not whether the instantiation of the template with those arguments
1740+
is valid. Generally speaking, there is no way to check that programmatically.
1741+
1742+
17281743
@subsection tutorial-introspection-sfinae Taking control of SFINAE
17291744
17301745
Doing something only if an expression is well-formed is a very common pattern
@@ -2024,7 +2039,10 @@ a container unspecified; they are explained in the
20242039
[rationales](@ref tutorial-rationales-container_representation).
20252040
When the representation of a container is implementation-defined, one must
20262041
be careful not to make any assumptions about it, unless those assumption
2027-
are explicitly allowed in the documentation of the container.
2042+
are explicitly allowed in the documentation of the container. For example,
2043+
assuming that one can safely inherit from a container or that the elements
2044+
in the container are stored in the same order as specified in its template
2045+
argument list is generally not safe.
20282046
20292047
20302048
@subsubsection tutorial-containers-types-overloading Overloading on container types
@@ -2817,9 +2835,12 @@ very useful for porting existing code from e.g. Fusion/MPL to Hana:
28172835
@snippet example/tutorial/ext/fusion_to_hana.cpp main
28182836
28192837
@note
2820-
At this time, only adapters to use data types from other libraries inside Hana
2821-
are provided; adapters for the other way around (using Hana containers inside
2822-
other libraries) are not provided.
2838+
- At this time, only adapters to use data types from other libraries inside Hana
2839+
are provided; adapters for the other way around (using Hana containers inside
2840+
other libraries) are not provided.
2841+
2842+
- The Fusion and MPL adapters are only guaranteed to work on the version of
2843+
Boost matching the version of Hana being used.
28232844
28242845
However, using external adapters has a couple of pitfalls. For example, after
28252846
a while using Hana, you might become used to comparing Hana tuples using the

example/map/difference.cpp

+14-15
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,23 @@
1010

1111
#include <string>
1212
namespace hana = boost::hana;
13-
using namespace hana::literals;
1413

1514

16-
constexpr auto m1 = hana::make_map(
17-
hana::make_pair("key1"_s, hana::type_c<std::string>),
18-
hana::make_pair("key2"_s, hana::type_c<std::string>)
15+
static auto m1 = hana::make_map(
16+
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
17+
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>)
1918
);
2019

21-
constexpr auto m2 = hana::make_map(
22-
hana::make_pair("key3"_s, hana::type_c<std::string>),
23-
hana::make_pair("key4"_s, hana::type_c<std::string>),
24-
hana::make_pair("key5"_s, hana::type_c<std::string>)
20+
static auto m2 = hana::make_map(
21+
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
22+
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
23+
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
2524
);
2625

27-
constexpr auto m3 = hana::make_map(
28-
hana::make_pair("key1"_s, hana::type_c<std::string>),
29-
hana::make_pair("key4"_s, hana::type_c<int>),
30-
hana::make_pair("key2"_s, hana::type_c<long long>)
26+
static auto m3 = hana::make_map(
27+
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
28+
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<int>),
29+
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<long long>)
3130
);
3231

3332
int main() {
@@ -36,11 +35,11 @@ int main() {
3635
BOOST_HANA_CONSTANT_CHECK(hana::difference(m1, m3) == hana::make_map());
3736

3837
BOOST_HANA_CONSTANT_CHECK(hana::difference(m3, m1) == hana::make_map(
39-
hana::make_pair("key4"_s, hana::type_c<int>)
38+
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<int>)
4039
));
4140

4241
BOOST_HANA_CONSTANT_CHECK(hana::difference(m2, m3) == hana::make_map(
43-
hana::make_pair("key3"_s, hana::type_c<std::string>),
44-
hana::make_pair("key5"_s, hana::type_c<std::string>)
42+
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
43+
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
4544
));
4645
}

example/map/intersection.cpp

+12-12
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,35 @@ namespace hana = boost::hana;
1313
using namespace hana::literals;
1414

1515

16-
constexpr auto m1 = hana::make_map(
17-
hana::make_pair("key1"_s, hana::type_c<std::string>),
18-
hana::make_pair("key2"_s, hana::type_c<std::string>)
16+
static auto m1 = hana::make_map(
17+
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
18+
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>)
1919
);
2020

21-
constexpr auto m2 = hana::make_map(
22-
hana::make_pair("key3"_s, hana::type_c<std::string>),
23-
hana::make_pair("key4"_s, hana::type_c<std::string>),
24-
hana::make_pair("key5"_s, hana::type_c<std::string>)
21+
static auto m2 = hana::make_map(
22+
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
23+
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
24+
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
2525
);
2626

2727
BOOST_HANA_CONSTANT_CHECK(hana::intersection(m1, m2) == hana::make_map());
2828

29-
constexpr auto m3 = hana::make_map(
29+
static auto m3 = hana::make_map(
3030
hana::make_pair(hana::type_c<int>, hana::int_c<1>),
3131
hana::make_pair(hana::type_c<bool>, hana::bool_c<true>),
32-
hana::make_pair(hana::type_c<std::string>, "hana"_s),
32+
hana::make_pair(hana::type_c<std::string>, BOOST_HANA_STRING("hana")),
3333
hana::make_pair(hana::type_c<float>, hana::int_c<100>)
3434
);
3535

36-
constexpr auto m4 = hana::make_map(
36+
static auto m4 = hana::make_map(
3737
hana::make_pair(hana::type_c<char>, hana::char_c<'c'>),
3838
hana::make_pair(hana::type_c<bool>, hana::bool_c<false>),
39-
hana::make_pair(hana::type_c<std::string>, "boost"_s)
39+
hana::make_pair(hana::type_c<std::string>, BOOST_HANA_STRING("boost"))
4040
);
4141

4242
BOOST_HANA_CONSTANT_CHECK(hana::intersection(m3, m4) == hana::make_map(
4343
hana::make_pair(hana::type_c<bool>, hana::bool_c<true>),
44-
hana::make_pair(hana::type_c<std::string>, "hana"_s)
44+
hana::make_pair(hana::type_c<std::string>, BOOST_HANA_STRING("hana"))
4545
));
4646

4747
int main() { }

example/map/union.cpp

+12-12
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,23 @@ namespace hana = boost::hana;
1515
using namespace hana::literals;
1616

1717

18-
constexpr auto m1 = hana::make_map(
19-
hana::make_pair("key1"_s, hana::type_c<std::string>),
20-
hana::make_pair("key2"_s, hana::type_c<std::string>)
18+
static auto m1 = hana::make_map(
19+
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
20+
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>)
2121
);
2222

23-
constexpr auto m2 = hana::make_map(
24-
hana::make_pair("key3"_s, hana::type_c<std::string>),
25-
hana::make_pair("key4"_s, hana::type_c<std::string>),
26-
hana::make_pair("key5"_s, hana::type_c<std::string>)
23+
static auto m2 = hana::make_map(
24+
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
25+
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
26+
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
2727
);
2828

2929
BOOST_HANA_CONSTANT_CHECK(hana::union_(m1, m2) == hana::make_map(
30-
hana::make_pair("key1"_s, hana::type_c<std::string>),
31-
hana::make_pair("key2"_s, hana::type_c<std::string>),
32-
hana::make_pair("key3"_s, hana::type_c<std::string>),
33-
hana::make_pair("key4"_s, hana::type_c<std::string>),
34-
hana::make_pair("key5"_s, hana::type_c<std::string>)
30+
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
31+
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>),
32+
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
33+
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
34+
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
3535
));
3636

3737
constexpr auto m3 = hana::make_map(

example/transform.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ int main() {
3333
BOOST_HANA_RUNTIME_CHECK(hana::transform(hana::just(123), to_string) == hana::just("123"s));
3434

3535
BOOST_HANA_CONSTANT_CHECK(
36-
hana::transform(hana::tuple_t<void, int(), char[10]>, hana::template_<std::add_pointer_t>)
36+
hana::transform(hana::tuple_t<void, int(), char[10]>, hana::metafunction<std::add_pointer>)
3737
==
3838
hana::tuple_t<void*, int(*)(), char(*)[10]>
3939
);

example/tuple/tuple_c.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace hana = boost::hana;
1313

1414
int main() {
1515
BOOST_HANA_CONSTANT_CHECK(
16-
hana::to_tuple(hana::tuple_c<int, 0, 1, 2>)
16+
hana::tuple_c<int, 0, 1, 2>
1717
==
1818
hana::make_tuple(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>)
1919
);

example/tutorial/introspection.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -139,3 +139,20 @@ BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
139139
BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
140140
//! [nested_template]
141141
}
142+
143+
namespace template_specialization {
144+
//! [template_specialization]
145+
template <typename T, typename U>
146+
struct Foo;
147+
148+
template <typename T>
149+
struct Bar;
150+
151+
auto is_binary_template = hana::is_valid([](auto trait) -> decltype(
152+
trait(hana::type_c<void>, hana::type_c<void>)
153+
) { });
154+
155+
BOOST_HANA_CONSTANT_CHECK(is_binary_template(hana::template_<Foo>));
156+
BOOST_HANA_CONSTANT_CHECK(!is_binary_template(hana::template_<Bar>));
157+
//! [template_specialization]
158+
}

include/boost/hana/empty.hpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,21 @@ Distributed under the Boost Software License, Version 1.0.
2020

2121

2222
BOOST_HANA_NAMESPACE_BEGIN
23+
//! @cond
2324
template <typename M>
24-
struct empty_t {
25+
constexpr auto empty_t<M>::operator()() const {
2526
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
2627
static_assert(hana::MonadPlus<M>::value,
2728
"hana::empty<M>() requires 'M' to be a MonadPlus");
2829
#endif
2930

30-
constexpr auto operator()() const {
31-
using Empty = BOOST_HANA_DISPATCH_IF(empty_impl<M>,
32-
hana::MonadPlus<M>::value
33-
);
31+
using Empty = BOOST_HANA_DISPATCH_IF(empty_impl<M>,
32+
hana::MonadPlus<M>::value
33+
);
3434

35-
return Empty::apply();
36-
}
37-
};
35+
return Empty::apply();
36+
}
37+
//! @endcond
3838

3939
template <typename M, bool condition>
4040
struct empty_impl<M, when<condition>> : default_ {

include/boost/hana/experimental/printable.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace experimental {
9999

100100
namespace print_detail {
101101
std::string strip_type_junk(std::string const& str) {
102-
return std::regex_replace(str, std::regex("^([a-z_]+::)*([a-z_]*)_t<"), "$2<");
102+
return std::regex_replace(str, std::regex("(?:struct )?([a-z_]+::)*([a-z_]*)_t<((?:struct )?[a-z:<>_]*)>"), "$2<$3>");
103103
}
104104
}
105105

include/boost/hana/ext/boost/mpl/vector.hpp

+17-1
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,25 @@ BOOST_HANA_NAMESPACE_BEGIN
9999
using vector_tag = ::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type;
100100
}}}
101101

102+
namespace mpl_detail {
103+
// When `BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES` is not defined (e.g. on
104+
// MSVC), different MPL sequences (like vector0 and vector1) have different
105+
// tags, so we need to take that into account when we compare them.
106+
#ifndef BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES
107+
template <typename T1, typename T2>
108+
struct is_same_mpl_vector_tag : std::false_type { };
109+
110+
template <template <long> class Tag, long x, long y>
111+
struct is_same_mpl_vector_tag<Tag<x>, Tag<y>> : std::true_type { };
112+
#else
113+
template <typename T1, typename T2>
114+
struct is_same_mpl_vector_tag : std::is_same<T1, T2> { };
115+
#endif
116+
}
117+
102118
template <typename T>
103119
struct tag_of<T, when<
104-
std::is_same<
120+
mpl_detail::is_same_mpl_vector_tag<
105121
typename ::boost::mpl::sequence_tag<T>::type,
106122
::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type
107123
>::value

include/boost/hana/fwd/basic_tuple.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ BOOST_HANA_NAMESPACE_BEGIN
2222
//! `std::tuple`, `basic_tuple` provides the strict minimum required to
2323
//! implement a closure with maximum compile-time efficiency.
2424
//!
25+
//! @note
26+
//! When you use a container, remember not to make assumptions about its
27+
//! representation, unless the documentation gives you those guarantees.
28+
//! More details [in the tutorial](@ref tutorial-containers-types).
29+
//!
2530
//!
2631
//! Modeled concepts
2732
//! ----------------

include/boost/hana/fwd/empty.hpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ BOOST_HANA_NAMESPACE_BEGIN
4141
struct empty_impl : empty_impl<M, when<true>> { };
4242

4343
template <typename M>
44-
struct empty_t;
44+
struct empty_t {
45+
constexpr auto operator()() const;
46+
};
4547

4648
template <typename M>
4749
constexpr empty_t<M> empty{};

include/boost/hana/fwd/lift.hpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ BOOST_HANA_NAMESPACE_BEGIN
4949
struct lift_impl : lift_impl<A, when<true>> { };
5050

5151
template <typename A>
52-
struct lift_t;
52+
struct lift_t {
53+
template <typename X>
54+
constexpr auto operator()(X&& x) const;
55+
};
5356

5457
template <typename A>
5558
constexpr lift_t<A> lift{};

include/boost/hana/fwd/map.hpp

+5-3
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,23 @@ BOOST_HANA_NAMESPACE_BEGIN
3636
//! keys must be `Hashable`, and any two keys with equal hashes must be
3737
//! `Comparable` with each other at compile-time.
3838
//!
39-
//! Note that the actual representation of a `hana::map` is an implementation
39+
//! @note
40+
//! The actual representation of a `hana::map` is an implementation
4041
//! detail. As such, one should not assume anything more than what is
4142
//! explicitly documented as being part of the interface of a map,
4243
//! such as:
4344
//! - the presence of additional constructors
4445
//! - the presence of additional assignment operators
4546
//! - the fact that `hana::map<Pairs...>` is, or is not, a dependent type
46-
//!
47+
//! .
4748
//! In particular, the last point is very important; `hana::map<Pairs...>`
4849
//! is basically equivalent to
4950
//! @code
5051
//! decltype(hana::make_pair(std::declval<Pairs>()...))
5152
//! @endcode
5253
//! which is not something that can be pattern-matched on during template
53-
//! argument deduction, for example.
54+
//! argument deduction, for example. More details [in the tutorial]
55+
//! (@ref tutorial-containers-types).
5456
//!
5557
//!
5658
//! Modeled concepts

include/boost/hana/fwd/monadic_fold_left.hpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,13 @@ BOOST_HANA_NAMESPACE_BEGIN
9494
struct monadic_fold_left_impl : monadic_fold_left_impl<T, when<true>> { };
9595

9696
template <typename M>
97-
struct monadic_fold_left_t;
97+
struct monadic_fold_left_t {
98+
template <typename Xs, typename State, typename F>
99+
constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const;
100+
101+
template <typename Xs, typename F>
102+
constexpr decltype(auto) operator()(Xs&& xs, F&& f) const;
103+
};
98104

99105
template <typename M>
100106
constexpr monadic_fold_left_t<M> monadic_fold_left{};

include/boost/hana/fwd/monadic_fold_right.hpp

+7-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,13 @@ BOOST_HANA_NAMESPACE_BEGIN
9696
struct monadic_fold_right_impl : monadic_fold_right_impl<T, when<true>> { };
9797

9898
template <typename M>
99-
struct monadic_fold_right_t;
99+
struct monadic_fold_right_t {
100+
template <typename Xs, typename State, typename F>
101+
constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const;
102+
103+
template <typename Xs, typename F>
104+
constexpr decltype(auto) operator()(Xs&& xs, F&& f) const;
105+
};
100106

101107
template <typename M>
102108
constexpr monadic_fold_right_t<M> monadic_fold_right{};

0 commit comments

Comments
 (0)