Skip to content

Commit 1970ee9

Browse files
committed
[to] Fix ambiguous conversion to the underlying type for integral constants
Fixes #354
1 parent 1aa52a9 commit 1970ee9

File tree

3 files changed

+62
-19
lines changed

3 files changed

+62
-19
lines changed

include/boost/hana/core/to.hpp

+21-19
Original file line numberDiff line numberDiff line change
@@ -39,27 +39,29 @@ BOOST_HANA_NAMESPACE_BEGIN
3939
namespace convert_detail {
4040
struct no_conversion { };
4141

42-
template <typename ...>
43-
struct is_valid { static constexpr bool value = true; };
44-
}
42+
template <typename To, typename From, typename = void>
43+
struct maybe_static_cast : no_conversion {
44+
template <typename X>
45+
static constexpr auto apply(X const&) {
46+
static_assert(detail::wrong<to_impl<To, From>, X>{},
47+
"no conversion is available between the provided types");
48+
}
49+
};
4550

46-
template <typename To, typename From, bool condition>
47-
struct to_impl<To, From, when<condition>> : convert_detail::no_conversion {
48-
template <typename X>
49-
static constexpr auto apply(X const&) {
50-
static_assert(detail::wrong<to_impl<To, From>, X>{},
51-
"no conversion is available between the provided types");
52-
}
53-
};
51+
template <typename To, typename From>
52+
struct maybe_static_cast<To, From, decltype((void)
53+
static_cast<To>(std::declval<From>())
54+
)> {
55+
template <typename X>
56+
static constexpr To apply(X&& x)
57+
{ return static_cast<To>(static_cast<X&&>(x)); }
58+
};
59+
} // end namespace convert_detail
5460

55-
template <typename To, typename From>
56-
struct to_impl<To, From, when<convert_detail::is_valid<
57-
decltype(static_cast<To>(std::declval<From>()))
58-
>::value>> {
59-
template <typename X>
60-
static constexpr To apply(X&& x)
61-
{ return static_cast<To>(static_cast<X&&>(x)); }
62-
};
61+
template <typename To, typename From, bool condition>
62+
struct to_impl<To, From, when<condition>>
63+
: convert_detail::maybe_static_cast<To, From>
64+
{ };
6365

6466
template <typename To>
6567
struct to_impl<To, To> : embedding<> {

test/concept/constant/to.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright Louis Dionne 2013-2017
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4+
5+
#include "minimal.hpp"
6+
7+
#include <boost/hana/concept/constant.hpp>
8+
#include <boost/hana/core/to.hpp>
9+
namespace hana = boost::hana;
10+
11+
12+
static_assert(hana::is_convertible<minimal_constant_tag<bool>, bool>::value, "");
13+
static_assert(hana::to<bool>(minimal_constant<bool, true>{}) == true, "");
14+
15+
static_assert(hana::is_convertible<minimal_constant_tag<int>, int>::value, "");
16+
static_assert(hana::to<int>(minimal_constant<int, 1>{}) == 1, "");
17+
18+
static_assert(hana::is_convertible<minimal_constant_tag<long>, long>::value, "");
19+
static_assert(hana::to<long>(minimal_constant<long, 1>{}) == 1l, "");
20+
21+
int main() { }

test/integral_constant/github_354.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright Louis Dionne 2013-2017
2+
// Distributed under the Boost Software License, Version 1.0.
3+
// (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
4+
5+
#include <boost/hana/bool.hpp>
6+
#include <boost/hana/core/to.hpp>
7+
#include <boost/hana/integral_constant.hpp>
8+
namespace hana = boost::hana;
9+
10+
11+
static_assert(hana::is_convertible<hana::bool_<true>, bool>::value, "");
12+
static_assert(hana::to<bool>(hana::bool_c<true>) == true, "");
13+
14+
static_assert(hana::is_convertible<hana::integral_constant<int, 1>, int>::value, "");
15+
static_assert(hana::to<int>(hana::integral_c<int, 1>) == 1, "");
16+
17+
static_assert(hana::is_convertible<hana::integral_constant<long, 1l>, long>::value, "");
18+
static_assert(hana::to<long>(hana::integral_c<long, 1l>) == 1l, "");
19+
20+
int main() { }

0 commit comments

Comments
 (0)