Skip to content

Commit

Permalink
Merging 'develop' into 'master' for 1.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ldionne committed Sep 3, 2020
2 parents bf42400 + 4f5157b commit 07eadfb
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 50 deletions.
11 changes: 3 additions & 8 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
Release notes for Hana 1.6.1
Release notes for Hana 1.7.0
============================

- Official support for Xcode 6, 7 and 8, 9, 10 and LLVM Clang 3.5, 3.6, 3.7,
and 3.8 has has been dropped. The library should still work with these
compilers, however they are not being tested regularly anymore, so they are
not officially supported.
- The `hana::traits::result_of` trait has been removed. Since `std::result_of`
has been removed from the Standard in C++20, users should move away from it.
- Disable the definition of traits::is_pod in C++20 and later, due to its
deprecation.
70 changes: 35 additions & 35 deletions doc/tutorial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3576,41 +3576,41 @@ in pseudo-code, the actual implementation sometimes being slightly hard to
understand. This section defines terms used in the reference and in the
pseudo-code used to describe some functions.
@anchor tutorial-glossary-forwarded
#### `forwarded(x)`
Means that the object is forwarded optimally. This means that if `x` is a
parameter, it is `std::forward`ed, and if it is a captured variable, it is
moved from whenever the enclosing lambda is an rvalue.
Also note that when `x` can be moved from, the statement `return forwarded(x);`
in a function with `decltype(auto)` does not mean that an rvalue reference to
`x` will be returned, which would create a dangling reference. Rather, it
means that `x` is returned by value, the value being constructed with the
`std::forward`ed `x`.
@anchor tutorial-glossary-perfect_capture
#### `perfect-capture`
This is used in lambdas to signify that the captured variables are
initialized using perfect forwarding, as if `[x(forwarded(x))...]() { }`
had been used.
@anchor tutorial-glossary-tag_dispatched
#### `tag-dispatched`
This means that the documented function uses [tag dispatching]
(@ref tutorial-core-tag_dispatching), and hence the exact
implementation depends on the model of the concept associated
to the function.
@anchor tutorial-glossary-implementation_defined
#### `implementation-defined`
This expresses the fact that the exact implementation of an entity (usually a
type) should not be relied upon by users. In particular, this means that one
can not assume anything beyond what is written explicitly in the documentation.
Usually, the concepts satisfied by an implementation-defined entity will be
documented, because one could otherwise do nothing with it. Concretely,
assuming too much about an implementation-defined entity will probably
not kill you, but it will very probably break your code when you update
to a newer version of Hana.
- @anchor tutorial-glossary-forwarded `forwarded(x)`
Means that the object is forwarded optimally. This means that if `x` is a
parameter, it is `std::forward`ed, and if it is a captured variable, it is
moved from whenever the enclosing lambda is an rvalue.
Also note that when `x` can be moved from, the statement `return forwarded(x);`
in a function with `decltype(auto)` does not mean that an rvalue reference to
`x` will be returned, which would create a dangling reference. Rather, it
means that `x` is returned by value, the value being constructed with the
`std::forward`ed `x`.
- @anchor tutorial-glossary-perfect_capture `perfect-capture`
This is used in lambdas to signify that the captured variables are
initialized using perfect forwarding, as if `[x(forwarded(x))...]() { }`
had been used.
- @anchor tutorial-glossary-tag_dispatched `tag-dispatched`
This means that the documented function uses [tag dispatching]
(@ref tutorial-core-tag_dispatching), and hence the exact
implementation depends on the model of the concept associated
to the function.
- @anchor tutorial-glossary-implementation_defined `implementation-defined`
This expresses the fact that the exact implementation of an entity (usually a
type) should not be relied upon by users. In particular, this means that one
can not assume anything beyond what is written explicitly in the documentation.
Usually, the concepts satisfied by an implementation-defined entity will be
documented, because one could otherwise do nothing with it. Concretely,
assuming too much about an implementation-defined entity will probably
not kill you, but it will very probably break your code when you update
to a newer version of Hana.
Expand Down
10 changes: 10 additions & 0 deletions include/boost/hana/core/tag_of.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ Distributed under the Boost Software License, Version 1.0.
#include <boost/hana/config.hpp>
#include <boost/hana/core/when.hpp>

#include <type_traits>


BOOST_HANA_NAMESPACE_BEGIN
//! @cond
Expand Down Expand Up @@ -44,6 +46,14 @@ BOOST_HANA_NAMESPACE_BEGIN
template <typename T> struct tag_of<T const volatile> : tag_of<T> { };
template <typename T> struct tag_of<T&> : tag_of<T> { };
template <typename T> struct tag_of<T&&> : tag_of<T> { };

namespace detail {
template <typename T>
struct has_idempotent_tag
: std::is_same<hana::tag_of_t<T>,
std::remove_const_t<std::remove_reference_t<T>>>
{ };
}
BOOST_HANA_NAMESPACE_END

#endif // !BOOST_HANA_CORE_TAG_OF_HPP
16 changes: 12 additions & 4 deletions include/boost/hana/detail/operators/comparable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,23 @@ BOOST_HANA_NAMESPACE_BEGIN namespace detail {

namespace operators {
template <typename X, typename Y, typename = typename std::enable_if<
detail::comparable_operators<typename hana::tag_of<X>::type>::value ||
detail::comparable_operators<typename hana::tag_of<Y>::type>::value
!detail::has_idempotent_tag<X>::value &&
!detail::has_idempotent_tag<Y>::value &&
(detail::comparable_operators<
typename hana::tag_of<X>::type>::value ||
detail::comparable_operators<
typename hana::tag_of<Y>::type>::value)
>::type>
constexpr auto operator==(X&& x, Y&& y)
{ return hana::equal(static_cast<X&&>(x), static_cast<Y&&>(y)); }

template <typename X, typename Y, typename = typename std::enable_if<
detail::comparable_operators<typename hana::tag_of<X>::type>::value ||
detail::comparable_operators<typename hana::tag_of<Y>::type>::value
!detail::has_idempotent_tag<X>::value &&
!detail::has_idempotent_tag<Y>::value &&
(detail::comparable_operators<
typename hana::tag_of<X>::type>::value ||
detail::comparable_operators<
typename hana::tag_of<Y>::type>::value)
>::type>
constexpr auto operator!=(X&& x, Y&& y)
{ return hana::not_equal(static_cast<X&&>(x), static_cast<Y&&>(y)); }
Expand Down
5 changes: 4 additions & 1 deletion include/boost/hana/equal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,10 @@ BOOST_HANA_NAMESPACE_BEGIN
}

template <typename S>
struct equal_impl<S, S, when<hana::Struct<S>::value>> {
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>(),
Expand Down
2 changes: 2 additions & 0 deletions include/boost/hana/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,9 @@ BOOST_HANA_NAMESPACE_BEGIN namespace traits {
constexpr auto is_trivial = detail::hana_trait<std::is_trivial>{};
constexpr auto is_trivially_copyable = detail::hana_trait<std::is_trivially_copyable>{};
constexpr auto is_standard_layout = detail::hana_trait<std::is_standard_layout>{};
#if __cplusplus < 202002L
constexpr auto is_pod = detail::hana_trait<std::is_pod>{};
#endif
constexpr auto is_literal_type = detail::hana_trait<std::is_literal_type>{};
constexpr auto is_empty = detail::hana_trait<std::is_empty>{};
constexpr auto is_polymorphic = detail::hana_trait<std::is_polymorphic>{};
Expand Down
4 changes: 2 additions & 2 deletions include/boost/hana/version.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ Distributed under the Boost Software License, Version 1.0.

//! @ingroup group-config
//! Macro expanding to the minor version of the library, i.e. the `y` in `x.y.z`.
#define BOOST_HANA_MINOR_VERSION 6
#define BOOST_HANA_MINOR_VERSION 7

//! @ingroup group-config
//! Macro expanding to the patch level of the library, i.e. the `z` in `x.y.z`.
#define BOOST_HANA_PATCH_VERSION 1
#define BOOST_HANA_PATCH_VERSION 0

//! @ingroup group-config
//! Macro expanding to the full version of the library, in hexadecimal
Expand Down
27 changes: 27 additions & 0 deletions test/issues/github_460.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright Jason Rice 2020
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/define_struct.hpp>
#include <boost/hana/equal.hpp>
#include <boost/hana/members.hpp>
#include <boost/hana/not_equal.hpp>
namespace hana = boost::hana;


struct SomeStruct {
BOOST_HANA_DEFINE_STRUCT(SomeStruct, (int, x));

constexpr bool operator==(SomeStruct const& other) {
return hana::equal(hana::members(*this), hana::members(other));
}

constexpr bool operator!=(SomeStruct const& other) {
return hana::not_equal(hana::members(*this), hana::members(other));
}
};

int main() {
static_assert(SomeStruct{5} == SomeStruct{5}, "");
static_assert(hana::equal(SomeStruct{5}, SomeStruct{5}), "");
}
39 changes: 39 additions & 0 deletions test/issues/github_470.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright Jason Rice 2020
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)

#include <boost/hana/equal.hpp>
#include <boost/hana/not_equal.hpp>
#include <boost/hana/tuple.hpp>
#include <cassert>
namespace hana = boost::hana;

namespace {
template <typename T>
struct optional {
T t;
};

template <typename T>
constexpr bool operator==(optional<T> const& o, T const& t) {
return o.t == t;
}
template <typename T>
constexpr bool operator==(T const& t, optional<T> const& o) {
return o.t == t;
}
template <typename T>
constexpr bool operator!=(optional<T> const& o, T const& t) {
return o.t != t;
}
template <typename T>
constexpr bool operator!=(T const& t, optional<T> const& o) {
return o.t != t;
}
}

int main() {
boost::hana::tuple<int> x{};
optional<boost::hana::tuple<int>> attr{x};
assert(attr == x); // <-- Kablooey!
}
2 changes: 2 additions & 0 deletions test/type/traits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ int main() {
hana::traits::is_trivial(s);
hana::traits::is_trivially_copyable(s);
hana::traits::is_standard_layout(s);
#if __cplusplus < 202002L
hana::traits::is_pod(s);
#endif
hana::traits::is_literal_type(s);
hana::traits::is_empty(s);
hana::traits::is_polymorphic(s);
Expand Down

0 comments on commit 07eadfb

Please sign in to comment.