Skip to content

Commit 9fe9d2f

Browse files
committed
Make sure concepts inherit from an integral_constant
Fixes #269
1 parent b87213e commit 9fe9d2f

Some content is hidden

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

46 files changed

+499
-383
lines changed

doc/tutorial.hpp

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3077,14 +3077,14 @@ conjunction with `hana::when` to achieve a great deal of expressiveness.
30773077
@subsection tutorial-core-concepts Emulation of C++ concepts
30783078
30793079
The implementation of concepts in Hana is very simple. At its heart, a concept
3080-
is just a template `struct` with a nested `::%value` boolean representing
3081-
whether the given type is a _model_ of the concept:
3080+
is just a template `struct` that inherits from a boolean `integral_constant`
3081+
representing whether the given type is a _model_ of the concept:
30823082
30833083
@code{cpp}
30843084
template <typename T>
3085-
struct Concept {
3086-
static constexpr bool value = whether T models Concept;
3087-
};
3085+
struct Concept
3086+
: hana::integral_constant<bool, whether T models Concept>
3087+
{ };
30883088
@endcode
30893089
30903090
Then, one can test whether a type `T` is a model of `Concept` by looking at
@@ -3108,9 +3108,9 @@ that can be `print`ed. Our end goal is to have a template struct such as
31083108
31093109
@code{cpp}
31103110
template <typename T>
3111-
struct Printable {
3112-
static constexpr bool value = whether print_impl<tag of T> is defined;
3113-
};
3111+
struct Printable
3112+
: hana::integral_constant<bool, whether print_impl<tag of T> is defined>
3113+
{ };
31143114
@endcode
31153115
31163116
To know whether `print_impl<...>` has been defined, we'll modify `print_impl`
@@ -3124,14 +3124,13 @@ inherit from that `special_base_class` type:
31243124
31253125
@snippet example/tutorial/concepts.cpp special_base_class_customize
31263126
3127-
As you can see, `Printable<T>::%value` really only checks whether the
3128-
`print_impl<T>` struct was specialized by a custom type. In particular,
3129-
it does not even check whether the nested `::%apply` function is defined
3130-
or if it is syntactically valid. It is assumed that if one specializes
3131-
`print_impl` for a custom type, the nested `::%apply` function exists and
3132-
is correct. If it is not, a compilation error will be triggered when one
3133-
tries to call `print` on an object of that type. Concepts in Hana make the
3134-
same assumptions.
3127+
As you can see, `Printable<T>` really only checks whether the `print_impl<T>`
3128+
struct was specialized by a custom type. In particular, it does not even check
3129+
whether the nested `::%apply` function is defined or if it is syntactically
3130+
valid. It is assumed that if one specializes `print_impl` for a custom type,
3131+
the nested `::%apply` function exists and is correct. If it is not, a compilation
3132+
error will be triggered when one tries to call `print` on an object of that type.
3133+
Concepts in Hana make the same assumptions.
31353134
31363135
Since this pattern of inheriting from a special base class is quite abundant
31373136
in Hana, the library provides a dummy type called `hana::default_` that can be

example/tutorial/concepts.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <boost/hana/core/default.hpp>
66
#include <boost/hana/core/tag_of.hpp>
7+
#include <boost/hana/integral_constant.hpp>
78

89
#include <string>
910
#include <type_traits>
@@ -21,10 +22,11 @@ struct print_impl : special_base_class {
2122
};
2223

2324
template <typename T>
24-
struct Printable {
25-
using Tag = hana::tag_of_t<T>;
26-
static constexpr bool value = !std::is_base_of<special_base_class, print_impl<Tag>>::value;
27-
};
25+
struct Printable
26+
: hana::integral_constant<bool,
27+
!std::is_base_of<special_base_class, print_impl<hana::tag_of_t<T>>>::value
28+
>
29+
{ };
2830
//! [special_base_class]
2931

3032
//! [special_base_class_customize]
@@ -49,10 +51,11 @@ struct print_impl : hana::default_ {
4951
};
5052

5153
template <typename T>
52-
struct Printable {
53-
using Tag = hana::tag_of_t<T>;
54-
static constexpr bool value = !hana::is_default<print_impl<Tag>>::value;
55-
};
54+
struct Printable
55+
: hana::integral_constant<bool,
56+
!hana::is_default<print_impl<hana::tag_of_t<T>>>::value
57+
>
58+
{ };
5659
//! [actual]
5760

5861
static_assert(!Printable<void>::value, "");

include/boost/hana/concept/applicative.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@ Distributed under the Boost Software License, Version 1.0.
1616
#include <boost/hana/config.hpp>
1717
#include <boost/hana/core/default.hpp>
1818
#include <boost/hana/core/tag_of.hpp>
19+
#include <boost/hana/detail/integral_constant.hpp>
1920
#include <boost/hana/lift.hpp>
2021

2122

2223
BOOST_HANA_NAMESPACE_BEGIN
2324
template <typename A>
24-
struct Applicative {
25-
using Tag = typename tag_of<A>::type;
26-
static constexpr bool value = !is_default<ap_impl<Tag>>::value &&
27-
!is_default<lift_impl<Tag>>::value;
28-
};
25+
struct Applicative
26+
: hana::integral_constant<bool,
27+
!is_default<ap_impl<typename tag_of<A>::type>>::value &&
28+
!is_default<lift_impl<typename tag_of<A>::type>>::value
29+
>
30+
{ };
2931
BOOST_HANA_NAMESPACE_END
3032

3133
#endif // !BOOST_HANA_CONCEPT_APPLICATIVE_HPP

include/boost/hana/concept/comonad.hpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,21 @@ Distributed under the Boost Software License, Version 1.0.
1515
#include <boost/hana/config.hpp>
1616
#include <boost/hana/core/default.hpp>
1717
#include <boost/hana/core/tag_of.hpp>
18+
#include <boost/hana/detail/integral_constant.hpp>
1819
#include <boost/hana/duplicate.hpp>
1920
#include <boost/hana/extend.hpp>
2021
#include <boost/hana/extract.hpp>
2122

2223

2324
BOOST_HANA_NAMESPACE_BEGIN
2425
template <typename W>
25-
struct Comonad {
26-
using Tag = typename tag_of<W>::type;
27-
static constexpr bool value = !is_default<extract_impl<Tag>>::value &&
28-
(!is_default<duplicate_impl<Tag>>::value ||
29-
!is_default<extend_impl<Tag>>::value);
30-
};
26+
struct Comonad
27+
: hana::integral_constant<bool,
28+
!is_default<extract_impl<typename tag_of<W>::type>>::value &&
29+
(!is_default<duplicate_impl<typename tag_of<W>::type>>::value ||
30+
!is_default<extend_impl<typename tag_of<W>::type>>::value)
31+
>
32+
{ };
3133
BOOST_HANA_NAMESPACE_END
3234

3335
#endif // !BOOST_HANA_CONCEPT_COMONAD_HPP

include/boost/hana/concept/comparable.hpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,18 @@ Distributed under the Boost Software License, Version 1.0.
1515
#include <boost/hana/config.hpp>
1616
#include <boost/hana/core/default.hpp>
1717
#include <boost/hana/core/tag_of.hpp>
18+
#include <boost/hana/detail/integral_constant.hpp>
1819
#include <boost/hana/equal.hpp>
1920

2021

2122
BOOST_HANA_NAMESPACE_BEGIN
2223
template <typename T>
23-
struct Comparable {
24-
using Tag = typename tag_of<T>::type;
25-
static constexpr bool value = !is_default<equal_impl<Tag, Tag>>::value;
26-
};
24+
struct Comparable
25+
: hana::integral_constant<bool,
26+
!is_default<equal_impl<typename tag_of<T>::type,
27+
typename tag_of<T>::type>>::value
28+
>
29+
{ };
2730
BOOST_HANA_NAMESPACE_END
2831

2932
#endif // !BOOST_HANA_CONCEPT_COMPARABLE_HPP

include/boost/hana/concept/constant.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,17 @@ Distributed under the Boost Software License, Version 1.0.
1515
#include <boost/hana/config.hpp>
1616
#include <boost/hana/core/default.hpp>
1717
#include <boost/hana/core/tag_of.hpp>
18+
#include <boost/hana/detail/integral_constant.hpp>
1819
#include <boost/hana/value.hpp>
1920

2021

2122
BOOST_HANA_NAMESPACE_BEGIN
2223
template <typename C>
23-
struct Constant {
24-
using Tag = typename tag_of<C>::type;
25-
static constexpr bool value = !is_default<value_impl<Tag>>::value;
26-
};
24+
struct Constant
25+
: hana::integral_constant<bool,
26+
!is_default<value_impl<typename tag_of<C>::type>>::value
27+
>
28+
{ };
2729
BOOST_HANA_NAMESPACE_END
2830

2931
#endif // !BOOST_HANA_CONCEPT_CONSTANT_HPP

include/boost/hana/concept/euclidean_ring.hpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,21 @@ Distributed under the Boost Software License, Version 1.0.
1515
#include <boost/hana/config.hpp>
1616
#include <boost/hana/core/default.hpp>
1717
#include <boost/hana/core/tag_of.hpp>
18+
#include <boost/hana/detail/integral_constant.hpp>
1819
#include <boost/hana/div.hpp>
1920
#include <boost/hana/mod.hpp>
2021

2122

2223
BOOST_HANA_NAMESPACE_BEGIN
2324
template <typename R>
24-
struct EuclideanRing {
25-
using Tag = typename tag_of<R>::type;
26-
static constexpr bool value = !is_default<mod_impl<Tag, Tag>>::value &&
27-
!is_default<div_impl<Tag, Tag>>::value;
28-
};
25+
struct EuclideanRing
26+
: hana::integral_constant<bool,
27+
!is_default<mod_impl<typename tag_of<R>::type,
28+
typename tag_of<R>::type>>::value &&
29+
!is_default<div_impl<typename tag_of<R>::type,
30+
typename tag_of<R>::type>>::value
31+
>
32+
{ };
2933
BOOST_HANA_NAMESPACE_END
3034

3135
#endif // !BOOST_HANA_CONCEPT_EUCLIDEAN_RING_HPP

include/boost/hana/concept/foldable.hpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,19 @@ Distributed under the Boost Software License, Version 1.0.
1515
#include <boost/hana/config.hpp>
1616
#include <boost/hana/core/default.hpp>
1717
#include <boost/hana/core/tag_of.hpp>
18+
#include <boost/hana/detail/integral_constant.hpp>
1819
#include <boost/hana/fold_left.hpp>
1920
#include <boost/hana/unpack.hpp>
2021

2122

2223
BOOST_HANA_NAMESPACE_BEGIN
2324
template <typename T>
24-
struct Foldable {
25-
using Tag = typename tag_of<T>::type;
26-
static constexpr bool value = !is_default<fold_left_impl<Tag>>::value ||
27-
!is_default<unpack_impl<Tag>>::value;
28-
};
25+
struct Foldable
26+
: hana::integral_constant<bool,
27+
!is_default<fold_left_impl<typename tag_of<T>::type>>::value ||
28+
!is_default<unpack_impl<typename tag_of<T>::type>>::value
29+
>
30+
{ };
2931
BOOST_HANA_NAMESPACE_END
3032

3133
#endif // !BOOST_HANA_CONCEPT_FOLDABLE_HPP

include/boost/hana/concept/functor.hpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,22 @@ Distributed under the Boost Software License, Version 1.0.
1212

1313
#include <boost/hana/fwd/concept/functor.hpp>
1414

15-
#include <boost/hana/config.hpp>
1615
#include <boost/hana/adjust_if.hpp>
16+
#include <boost/hana/config.hpp>
1717
#include <boost/hana/core/default.hpp>
1818
#include <boost/hana/core/tag_of.hpp>
19+
#include <boost/hana/detail/integral_constant.hpp>
1920
#include <boost/hana/transform.hpp>
2021

2122

2223
BOOST_HANA_NAMESPACE_BEGIN
2324
template <typename F>
24-
struct Functor {
25-
using Tag = typename tag_of<F>::type;
26-
static constexpr bool value = !is_default<transform_impl<Tag>>::value ||
27-
!is_default<adjust_if_impl<Tag>>::value;
28-
};
25+
struct Functor
26+
: hana::integral_constant<bool,
27+
!is_default<transform_impl<typename tag_of<F>::type>>::value ||
28+
!is_default<adjust_if_impl<typename tag_of<F>::type>>::value
29+
>
30+
{ };
2931
BOOST_HANA_NAMESPACE_END
3032

3133
#endif // !BOOST_HANA_CONCEPT_FUNCTOR_HPP

include/boost/hana/concept/group.hpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,20 @@ Distributed under the Boost Software License, Version 1.0.
1515
#include <boost/hana/config.hpp>
1616
#include <boost/hana/core/default.hpp>
1717
#include <boost/hana/core/tag_of.hpp>
18+
#include <boost/hana/detail/integral_constant.hpp>
1819
#include <boost/hana/minus.hpp>
1920
#include <boost/hana/negate.hpp>
2021

2122

2223
BOOST_HANA_NAMESPACE_BEGIN
2324
template <typename G>
24-
struct Group {
25-
using Tag = typename tag_of<G>::type;
26-
static constexpr bool value = !is_default<negate_impl<Tag>>::value ||
27-
!is_default<minus_impl<Tag, Tag>>::value;
28-
};
25+
struct Group
26+
: hana::integral_constant<bool,
27+
!is_default<negate_impl<typename tag_of<G>::type>>::value ||
28+
!is_default<minus_impl<typename tag_of<G>::type,
29+
typename tag_of<G>::type>>::value
30+
>
31+
{ };
2932
BOOST_HANA_NAMESPACE_END
3033

3134
#endif // !BOOST_HANA_CONCEPT_GROUP_HPP

0 commit comments

Comments
 (0)