Skip to content

Commit

Permalink
Merge develop into master for release 1.5.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ldionne committed Jul 6, 2018
2 parents e53c547 + 1e1bedb commit 6187d44
Show file tree
Hide file tree
Showing 51 changed files with 454 additions and 251 deletions.
33 changes: 27 additions & 6 deletions doc/tutorial.hpp
Expand Up @@ -1703,7 +1703,7 @@ that type and cast it to `void`, for the same reason as we did for non-static
members.
@subsubsection tutorial-introspection-is_valid-typename Nested type names
@subsubsection tutorial-introspection-is_valid-nested-typename Nested type names
Checking for a nested type name is not hard, but it is slightly more
convoluted than the previous cases:
Expand All @@ -1716,7 +1716,7 @@ support types that can't be returned from functions, like array types or
incomplete types.
@subsubsection tutorial-introspection-is_valid-template Nested templates
@subsubsection tutorial-introspection-is_valid-nested-template Nested templates
Checking for a nested template name is similar to checking for a nested type
name, except we use the `template_<...>` variable template instead of
Expand All @@ -1725,6 +1725,21 @@ name, except we use the `template_<...>` variable template instead of
@snippet example/tutorial/introspection.cpp nested_template
@subsubsection tutorial-introspection-is_valid-template Template specializations
Checking whether a template specialization is valid can be done too, but we
now pass a `template_<...>` to `is_valid` instead of a `type<...>`, because
that's what we want to make the check on:
@snippet example/tutorial/introspection.cpp template_specialization
@note
Doing this will not cause the template to be instantiated. Hence, it will only
check whether the given template can be mentioned with the provided template
arguments, not whether the instantiation of the template with those arguments
is valid. Generally speaking, there is no way to check that programmatically.
@subsection tutorial-introspection-sfinae Taking control of SFINAE
Doing something only if an expression is well-formed is a very common pattern
Expand Down Expand Up @@ -2024,7 +2039,10 @@ a container unspecified; they are explained in the
[rationales](@ref tutorial-rationales-container_representation).
When the representation of a container is implementation-defined, one must
be careful not to make any assumptions about it, unless those assumption
are explicitly allowed in the documentation of the container.
are explicitly allowed in the documentation of the container. For example,
assuming that one can safely inherit from a container or that the elements
in the container are stored in the same order as specified in its template
argument list is generally not safe.
@subsubsection tutorial-containers-types-overloading Overloading on container types
Expand Down Expand Up @@ -2817,9 +2835,12 @@ very useful for porting existing code from e.g. Fusion/MPL to Hana:
@snippet example/tutorial/ext/fusion_to_hana.cpp main
@note
At this time, only adapters to use data types from other libraries inside Hana
are provided; adapters for the other way around (using Hana containers inside
other libraries) are not provided.
- At this time, only adapters to use data types from other libraries inside Hana
are provided; adapters for the other way around (using Hana containers inside
other libraries) are not provided.
- The Fusion and MPL adapters are only guaranteed to work on the version of
Boost matching the version of Hana being used.
However, using external adapters has a couple of pitfalls. For example, after
a while using Hana, you might become used to comparing Hana tuples using the
Expand Down
29 changes: 14 additions & 15 deletions example/map/difference.cpp
Expand Up @@ -10,24 +10,23 @@

#include <string>
namespace hana = boost::hana;
using namespace hana::literals;


constexpr auto m1 = hana::make_map(
hana::make_pair("key1"_s, hana::type_c<std::string>),
hana::make_pair("key2"_s, hana::type_c<std::string>)
static auto m1 = hana::make_map(
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>)
);

constexpr auto m2 = hana::make_map(
hana::make_pair("key3"_s, hana::type_c<std::string>),
hana::make_pair("key4"_s, hana::type_c<std::string>),
hana::make_pair("key5"_s, hana::type_c<std::string>)
static auto m2 = hana::make_map(
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
);

constexpr auto m3 = hana::make_map(
hana::make_pair("key1"_s, hana::type_c<std::string>),
hana::make_pair("key4"_s, hana::type_c<int>),
hana::make_pair("key2"_s, hana::type_c<long long>)
static auto m3 = hana::make_map(
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<int>),
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<long long>)
);

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

BOOST_HANA_CONSTANT_CHECK(hana::difference(m3, m1) == hana::make_map(
hana::make_pair("key4"_s, hana::type_c<int>)
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<int>)
));

BOOST_HANA_CONSTANT_CHECK(hana::difference(m2, m3) == hana::make_map(
hana::make_pair("key3"_s, hana::type_c<std::string>),
hana::make_pair("key5"_s, hana::type_c<std::string>)
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
));
}
24 changes: 12 additions & 12 deletions example/map/intersection.cpp
Expand Up @@ -13,35 +13,35 @@ namespace hana = boost::hana;
using namespace hana::literals;


constexpr auto m1 = hana::make_map(
hana::make_pair("key1"_s, hana::type_c<std::string>),
hana::make_pair("key2"_s, hana::type_c<std::string>)
static auto m1 = hana::make_map(
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>)
);

constexpr auto m2 = hana::make_map(
hana::make_pair("key3"_s, hana::type_c<std::string>),
hana::make_pair("key4"_s, hana::type_c<std::string>),
hana::make_pair("key5"_s, hana::type_c<std::string>)
static auto m2 = hana::make_map(
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
);

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

constexpr auto m3 = hana::make_map(
static auto m3 = hana::make_map(
hana::make_pair(hana::type_c<int>, hana::int_c<1>),
hana::make_pair(hana::type_c<bool>, hana::bool_c<true>),
hana::make_pair(hana::type_c<std::string>, "hana"_s),
hana::make_pair(hana::type_c<std::string>, BOOST_HANA_STRING("hana")),
hana::make_pair(hana::type_c<float>, hana::int_c<100>)
);

constexpr auto m4 = hana::make_map(
static auto m4 = hana::make_map(
hana::make_pair(hana::type_c<char>, hana::char_c<'c'>),
hana::make_pair(hana::type_c<bool>, hana::bool_c<false>),
hana::make_pair(hana::type_c<std::string>, "boost"_s)
hana::make_pair(hana::type_c<std::string>, BOOST_HANA_STRING("boost"))
);

BOOST_HANA_CONSTANT_CHECK(hana::intersection(m3, m4) == hana::make_map(
hana::make_pair(hana::type_c<bool>, hana::bool_c<true>),
hana::make_pair(hana::type_c<std::string>, "hana"_s)
hana::make_pair(hana::type_c<std::string>, BOOST_HANA_STRING("hana"))
));

int main() { }
24 changes: 12 additions & 12 deletions example/map/union.cpp
Expand Up @@ -15,23 +15,23 @@ namespace hana = boost::hana;
using namespace hana::literals;


constexpr auto m1 = hana::make_map(
hana::make_pair("key1"_s, hana::type_c<std::string>),
hana::make_pair("key2"_s, hana::type_c<std::string>)
static auto m1 = hana::make_map(
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>)
);

constexpr auto m2 = hana::make_map(
hana::make_pair("key3"_s, hana::type_c<std::string>),
hana::make_pair("key4"_s, hana::type_c<std::string>),
hana::make_pair("key5"_s, hana::type_c<std::string>)
static auto m2 = hana::make_map(
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
);

BOOST_HANA_CONSTANT_CHECK(hana::union_(m1, m2) == hana::make_map(
hana::make_pair("key1"_s, hana::type_c<std::string>),
hana::make_pair("key2"_s, hana::type_c<std::string>),
hana::make_pair("key3"_s, hana::type_c<std::string>),
hana::make_pair("key4"_s, hana::type_c<std::string>),
hana::make_pair("key5"_s, hana::type_c<std::string>)
hana::make_pair(BOOST_HANA_STRING("key1"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key2"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key3"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key4"), hana::type_c<std::string>),
hana::make_pair(BOOST_HANA_STRING("key5"), hana::type_c<std::string>)
));

constexpr auto m3 = hana::make_map(
Expand Down
2 changes: 1 addition & 1 deletion example/transform.cpp
Expand Up @@ -33,7 +33,7 @@ int main() {
BOOST_HANA_RUNTIME_CHECK(hana::transform(hana::just(123), to_string) == hana::just("123"s));

BOOST_HANA_CONSTANT_CHECK(
hana::transform(hana::tuple_t<void, int(), char[10]>, hana::template_<std::add_pointer_t>)
hana::transform(hana::tuple_t<void, int(), char[10]>, hana::metafunction<std::add_pointer>)
==
hana::tuple_t<void*, int(*)(), char(*)[10]>
);
Expand Down
2 changes: 1 addition & 1 deletion example/tuple/tuple_c.cpp
Expand Up @@ -13,7 +13,7 @@ namespace hana = boost::hana;

int main() {
BOOST_HANA_CONSTANT_CHECK(
hana::to_tuple(hana::tuple_c<int, 0, 1, 2>)
hana::tuple_c<int, 0, 1, 2>
==
hana::make_tuple(hana::int_c<0>, hana::int_c<1>, hana::int_c<2>)
);
Expand Down
17 changes: 17 additions & 0 deletions example/tutorial/introspection.cpp
Expand Up @@ -139,3 +139,20 @@ BOOST_HANA_CONSTANT_CHECK(has_member(hana::type_c<Foo>));
BOOST_HANA_CONSTANT_CHECK(!has_member(hana::type_c<Bar>));
//! [nested_template]
}

namespace template_specialization {
//! [template_specialization]
template <typename T, typename U>
struct Foo;

template <typename T>
struct Bar;

auto is_binary_template = hana::is_valid([](auto trait) -> decltype(
trait(hana::type_c<void>, hana::type_c<void>)
) { });

BOOST_HANA_CONSTANT_CHECK(is_binary_template(hana::template_<Foo>));
BOOST_HANA_CONSTANT_CHECK(!is_binary_template(hana::template_<Bar>));
//! [template_specialization]
}
16 changes: 8 additions & 8 deletions include/boost/hana/empty.hpp
Expand Up @@ -20,21 +20,21 @@ Distributed under the Boost Software License, Version 1.0.


BOOST_HANA_NAMESPACE_BEGIN
//! @cond
template <typename M>
struct empty_t {
constexpr auto empty_t<M>::operator()() const {
#ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS
static_assert(hana::MonadPlus<M>::value,
"hana::empty<M>() requires 'M' to be a MonadPlus");
#endif

constexpr auto operator()() const {
using Empty = BOOST_HANA_DISPATCH_IF(empty_impl<M>,
hana::MonadPlus<M>::value
);
using Empty = BOOST_HANA_DISPATCH_IF(empty_impl<M>,
hana::MonadPlus<M>::value
);

return Empty::apply();
}
};
return Empty::apply();
}
//! @endcond

template <typename M, bool condition>
struct empty_impl<M, when<condition>> : default_ {
Expand Down
2 changes: 1 addition & 1 deletion include/boost/hana/experimental/printable.hpp
Expand Up @@ -99,7 +99,7 @@ BOOST_HANA_NAMESPACE_BEGIN namespace experimental {

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

Expand Down
18 changes: 17 additions & 1 deletion include/boost/hana/ext/boost/mpl/vector.hpp
Expand Up @@ -99,9 +99,25 @@ BOOST_HANA_NAMESPACE_BEGIN
using vector_tag = ::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type;
}}}

namespace mpl_detail {
// When `BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES` is not defined (e.g. on
// MSVC), different MPL sequences (like vector0 and vector1) have different
// tags, so we need to take that into account when we compare them.
#ifndef BOOST_MPL_CFG_TYPEOF_BASED_SEQUENCES
template <typename T1, typename T2>
struct is_same_mpl_vector_tag : std::false_type { };

template <template <long> class Tag, long x, long y>
struct is_same_mpl_vector_tag<Tag<x>, Tag<y>> : std::true_type { };
#else
template <typename T1, typename T2>
struct is_same_mpl_vector_tag : std::is_same<T1, T2> { };
#endif
}

template <typename T>
struct tag_of<T, when<
std::is_same<
mpl_detail::is_same_mpl_vector_tag<
typename ::boost::mpl::sequence_tag<T>::type,
::boost::mpl::sequence_tag< ::boost::mpl::vector<>>::type
>::value
Expand Down
5 changes: 5 additions & 0 deletions include/boost/hana/fwd/basic_tuple.hpp
Expand Up @@ -22,6 +22,11 @@ BOOST_HANA_NAMESPACE_BEGIN
//! `std::tuple`, `basic_tuple` provides the strict minimum required to
//! implement a closure with maximum compile-time efficiency.
//!
//! @note
//! When you use a container, remember not to make assumptions about its
//! representation, unless the documentation gives you those guarantees.
//! More details [in the tutorial](@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
//! ----------------
Expand Down
4 changes: 3 additions & 1 deletion include/boost/hana/fwd/empty.hpp
Expand Up @@ -41,7 +41,9 @@ BOOST_HANA_NAMESPACE_BEGIN
struct empty_impl : empty_impl<M, when<true>> { };

template <typename M>
struct empty_t;
struct empty_t {
constexpr auto operator()() const;
};

template <typename M>
constexpr empty_t<M> empty{};
Expand Down
5 changes: 4 additions & 1 deletion include/boost/hana/fwd/lift.hpp
Expand Up @@ -49,7 +49,10 @@ BOOST_HANA_NAMESPACE_BEGIN
struct lift_impl : lift_impl<A, when<true>> { };

template <typename A>
struct lift_t;
struct lift_t {
template <typename X>
constexpr auto operator()(X&& x) const;
};

template <typename A>
constexpr lift_t<A> lift{};
Expand Down
8 changes: 5 additions & 3 deletions include/boost/hana/fwd/map.hpp
Expand Up @@ -36,21 +36,23 @@ BOOST_HANA_NAMESPACE_BEGIN
//! keys must be `Hashable`, and any two keys with equal hashes must be
//! `Comparable` with each other at compile-time.
//!
//! Note that the actual representation of a `hana::map` is an implementation
//! @note
//! The actual representation of a `hana::map` is an implementation
//! detail. As such, one should not assume anything more than what is
//! explicitly documented as being part of the interface of a map,
//! such as:
//! - the presence of additional constructors
//! - the presence of additional assignment operators
//! - the fact that `hana::map<Pairs...>` is, or is not, a dependent type
//!
//! .
//! In particular, the last point is very important; `hana::map<Pairs...>`
//! is basically equivalent to
//! @code
//! decltype(hana::make_pair(std::declval<Pairs>()...))
//! @endcode
//! which is not something that can be pattern-matched on during template
//! argument deduction, for example.
//! argument deduction, for example. More details [in the tutorial]
//! (@ref tutorial-containers-types).
//!
//!
//! Modeled concepts
Expand Down
8 changes: 7 additions & 1 deletion include/boost/hana/fwd/monadic_fold_left.hpp
Expand Up @@ -94,7 +94,13 @@ BOOST_HANA_NAMESPACE_BEGIN
struct monadic_fold_left_impl : monadic_fold_left_impl<T, when<true>> { };

template <typename M>
struct monadic_fold_left_t;
struct monadic_fold_left_t {
template <typename Xs, typename State, typename F>
constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const;

template <typename Xs, typename F>
constexpr decltype(auto) operator()(Xs&& xs, F&& f) const;
};

template <typename M>
constexpr monadic_fold_left_t<M> monadic_fold_left{};
Expand Down
8 changes: 7 additions & 1 deletion include/boost/hana/fwd/monadic_fold_right.hpp
Expand Up @@ -96,7 +96,13 @@ BOOST_HANA_NAMESPACE_BEGIN
struct monadic_fold_right_impl : monadic_fold_right_impl<T, when<true>> { };

template <typename M>
struct monadic_fold_right_t;
struct monadic_fold_right_t {
template <typename Xs, typename State, typename F>
constexpr decltype(auto) operator()(Xs&& xs, State&& state, F&& f) const;

template <typename Xs, typename F>
constexpr decltype(auto) operator()(Xs&& xs, F&& f) const;
};

template <typename M>
constexpr monadic_fold_right_t<M> monadic_fold_right{};
Expand Down

0 comments on commit 6187d44

Please sign in to comment.