1 /*!
2 @file
3 Forward declares `boost::hana::when` and `boost::hana::when_valid`.
4 
5 @copyright Louis Dionne 2013-2017
6 Distributed under the Boost Software License, Version 1.0.
7 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
8  */
9 
10 #ifndef BOOST_HANA_FWD_CORE_WHEN_HPP
11 #define BOOST_HANA_FWD_CORE_WHEN_HPP
12 
13 #include <boost/hana/config.hpp>
14 
15 
16 namespace boost { namespace hana {
17     //! @ingroup group-core
18     //! Enable a partial specialization only if a boolean condition is true.
19     //!
20     //! You might also want to take a look at `when_valid`, which provides
21     //! similar functionality but enables a specialziation only when some
22     //! expression is well-formed.
23     //!
24     //! > #### Rationale for using `when` instead of `std::enable_if`
25     //! > `when` is used to control the priority of partial specializations
26     //! > in a finer grained manner than what can be achieved with the usual
27     //! > `typename Enable = void` and `std::enable_if` pattern. For example,
28     //! > a partially specialized tag-dispatched method will have a higher
29     //! > priority than an equivalent specialization that uses `when`. For
30     //! > more details, see the tutorial section on [tag-dispatching][1].
31     //!
32     //!
33     //! Example
34     //! -------
35     //! @include example/core/when.cpp
36     //!
37     //! [1]: @ref tutorial-core-tag_dispatching
38     template <bool condition>
39     struct when;
40 
41     namespace core_detail {
42         template <typename ...>
43         struct always_true { static constexpr bool value = true; };
44     }
45 
46     //! @ingroup group-core
47     //! Variant of `when` allowing specializations to be enabled only if an
48     //! expression is well-formed.
49     //!
50     //! `when_valid<...>` is always equivalent to `when<true>`. However, when
51     //! used inside a partial specialization, SFINAE will cause the partial
52     //! specialization to be ignored when the expression is ill-formed.
53     //!
54     //!
55     //! Example
56     //! -------
57     //! @include example/core/when_valid.cpp
58     //!
59     //!
60     //! @bug
61     //! Using `when_valid` seems to trigger ambiguous partial specializations
62     //! on GCC.
63 #ifdef BOOST_HANA_DOXYGEN_INVOKED
64     template <typename ...>
65     using when_valid = when<true>;
66 #else
67     template <typename ...Dummy>
68     using when_valid = when<
69         core_detail::always_true<Dummy...>::value
70     >;
71 #endif
72 }} // end namespace boost::hana
73 
74 #endif // !BOOST_HANA_FWD_CORE_WHEN_HPP
75