add boost on mac
This commit is contained in:
103
macx64/include/boost/hana/fwd/core/common.hpp
Normal file
103
macx64/include/boost/hana/fwd/core/common.hpp
Normal file
@@ -0,0 +1,103 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::common` and `boost::hana::common_t`.
|
||||
|
||||
@copyright Louis Dionne 2013-2017
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_FWD_CORE_COMMON_HPP
|
||||
#define BOOST_HANA_FWD_CORE_COMMON_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
BOOST_HANA_NAMESPACE_BEGIN
|
||||
//! @ingroup group-core
|
||||
//! %Metafunction returning the common data type between two data types.
|
||||
//!
|
||||
//! `common` is a natural extension of the `std::common_type` metafunction
|
||||
//! to data types. Given two data types `T` and `U`, we say that they share
|
||||
//! a common type `C` if both objects of data type `T` and objects of data
|
||||
//! type `U` may be converted (using `to`) to an object of data type `C`,
|
||||
//! and if that conversion is equality preserving. In other words, this
|
||||
//! means that for any objects `t1, t2` of data type `T` and `u1, u2` of
|
||||
//! data type `U`, the following law is satisfied:
|
||||
//! @code
|
||||
//! to<C>(t1) == to<C>(t2) if and only if t1 == t2
|
||||
//! to<C>(u1) == to<C>(u2) if and only if u1 == u2
|
||||
//! @endcode
|
||||
//!
|
||||
//! The role of `common` is to provide an alias to such a `C` if it exists.
|
||||
//! In other words, if `T` and `U` have a common data type `C`,
|
||||
//! `common<T, U>::%type` is an alias to `C`. Otherwise, `common<T, U>`
|
||||
//! has no nested `type` and can be used in dependent contexts to exploit
|
||||
//! SFINAE. By default, the exact steps followed by `common` to determine
|
||||
//! the common type `C` of `T` and `U` are
|
||||
//! 1. If `T` and `U` are the same, then `C` is `T`.
|
||||
//! 2. Otherwise, if `true ? std::declval<T>() : std::declval<U>()` is
|
||||
//! well-formed, then `C` is the type of this expression after using
|
||||
//! `std::decay` on it. This is exactly the type that would have been
|
||||
//! returned by `std::common_type`, except that custom specializations
|
||||
//! of `std::common_type` are not taken into account.
|
||||
//! 3. Otherwise, no common data type is detected and `common<T, U>` does
|
||||
//! not have a nested `type` alias, unless it is specialized explicitly.
|
||||
//!
|
||||
//! As point 3 suggests, it is also possible (and sometimes necessary) to
|
||||
//! specialize `common` in the `boost::hana` namespace for pairs of custom
|
||||
//! data types when the default behavior of `common` is not sufficient.
|
||||
//! Note that `when`-based specialization is supported when specializing
|
||||
//! `common` in the `boost::hana` namespace.
|
||||
//!
|
||||
//! > #### Rationale for requiring the conversion to be equality-preserving
|
||||
//! > This decision is aligned with a proposed concept design for the
|
||||
//! > standard library ([N3351][1]). Also, if we did not require this,
|
||||
//! > then all data types would trivially share the common data type
|
||||
//! > `void`, since all objects can be converted to it.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/common/common.cpp
|
||||
//!
|
||||
//!
|
||||
//! [1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename T, typename U, optional when-based enabler>
|
||||
struct common { see documentation };
|
||||
#else
|
||||
template <typename T, typename U, typename = void>
|
||||
struct common;
|
||||
#endif
|
||||
|
||||
//! @ingroup group-core
|
||||
//! %Metafunction returning whether two data types share a common data type.
|
||||
//!
|
||||
//! Given two data types `T` and `U`, this metafunction simply returns
|
||||
//! whether `common<T, U>::%type` is well-formed.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/common/has_common.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename T, typename U>
|
||||
struct has_common { whether common<T, U>::type is well-formed };
|
||||
#else
|
||||
template <typename T, typename U, typename = void>
|
||||
struct has_common;
|
||||
#endif
|
||||
|
||||
//! @ingroup group-core
|
||||
//! Alias to `common<T, U>::%type`, provided for convenience.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/common/common_t.cpp
|
||||
template <typename T, typename U>
|
||||
using common_t = typename common<T, U>::type;
|
||||
BOOST_HANA_NAMESPACE_END
|
||||
|
||||
#endif // !BOOST_HANA_FWD_CORE_COMMON_HPP
|
||||
56
macx64/include/boost/hana/fwd/core/default.hpp
Normal file
56
macx64/include/boost/hana/fwd/core/default.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::default_` and `boost::hana::is_default`.
|
||||
|
||||
@copyright Louis Dionne 2013-2017
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_FWD_CORE_DEFAULT_HPP
|
||||
#define BOOST_HANA_FWD_CORE_DEFAULT_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
BOOST_HANA_NAMESPACE_BEGIN
|
||||
//! @ingroup group-core
|
||||
//! Mark a tag-dispatched method implementation as a default implementation.
|
||||
//!
|
||||
//! When defining a new concept with tag-dispatched methods, it is
|
||||
//! sometimes possible to provide a default implementation for some
|
||||
//! method(s). Making `default_` a base class of such a default
|
||||
//! implementation makes it possible to detect whether the method
|
||||
//! was dispatched to the default implementation afterwards.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/default.cpp
|
||||
struct default_ { };
|
||||
|
||||
//! @ingroup group-core
|
||||
//! Returns whether a tag-dispatched method implementation is a default
|
||||
//! implementation.
|
||||
//!
|
||||
//! Given a tag-dispatched method implementation `method_impl<T...>`,
|
||||
//! `is_default<method_impl<T...>>` returns whether `method_impl<T...>`
|
||||
//! is a default implementation. Note that if there is no default
|
||||
//! implementation for the method, then `is_default` should not be
|
||||
//! used unless a static assertion saying that "the method is not
|
||||
//! implemented" is acceptable.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/default.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename Method>
|
||||
struct is_default { see documentation };
|
||||
#else
|
||||
template <typename T, typename = void>
|
||||
struct is_default;
|
||||
#endif
|
||||
BOOST_HANA_NAMESPACE_END
|
||||
|
||||
#endif // !BOOST_HANA_FWD_CORE_DEFAULT_HPP
|
||||
61
macx64/include/boost/hana/fwd/core/is_a.hpp
Normal file
61
macx64/include/boost/hana/fwd/core/is_a.hpp
Normal file
@@ -0,0 +1,61 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::is_a` and `boost::hana::is_an`.
|
||||
|
||||
@copyright Louis Dionne 2013-2017
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_FWD_CORE_IS_A_HPP
|
||||
#define BOOST_HANA_FWD_CORE_IS_A_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
BOOST_HANA_NAMESPACE_BEGIN
|
||||
//! @ingroup group-core
|
||||
//! Returns whether the tag of an object matches a given tag.
|
||||
//!
|
||||
//! Given a tag `Tag` and a C++ type `T`, `is_a<Tag, T>` is a compile-time
|
||||
//! Logical representing whether the tag of `T` is exactly `Tag`. In other
|
||||
//! words, it is equivalent to
|
||||
//! @code
|
||||
//! std::is_same<Tag, tag_of<T>::type>
|
||||
//! @endcode
|
||||
//!
|
||||
//! For convenience, an alternate syntax is provided for using `is_a`.
|
||||
//! Specifically, `is_a<Tag>` is a function object returning whether the
|
||||
//! argument it is passed has the given tag. In other words,
|
||||
//! @code
|
||||
//! is_a<Tag>(x) == is_a<Tag, decltype(x)>
|
||||
//! @endcode
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/is_a.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename Tag, typename optional_T>
|
||||
constexpr auto is_a = see-documentation;
|
||||
#else
|
||||
template <typename Tag, typename ...T>
|
||||
struct is_a_t;
|
||||
|
||||
template <typename Tag, typename ...T>
|
||||
constexpr is_a_t<Tag, T...> is_a{};
|
||||
#endif
|
||||
|
||||
//! @ingroup group-core
|
||||
//! Equivalent to `is_a`; provided for consistency with the rules of the
|
||||
//! English language.
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename Tag, typename ...T>
|
||||
constexpr auto is_an = is_a<Tag, T...>;
|
||||
#else
|
||||
template <typename Tag, typename ...T>
|
||||
constexpr is_a_t<Tag, T...> is_an{};
|
||||
#endif
|
||||
BOOST_HANA_NAMESPACE_END
|
||||
|
||||
#endif // !BOOST_HANA_FWD_CORE_IS_A_HPP
|
||||
70
macx64/include/boost/hana/fwd/core/make.hpp
Normal file
70
macx64/include/boost/hana/fwd/core/make.hpp
Normal file
@@ -0,0 +1,70 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::make`.
|
||||
|
||||
@copyright Louis Dionne 2013-2017
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_FWD_CORE_MAKE_HPP
|
||||
#define BOOST_HANA_FWD_CORE_MAKE_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
BOOST_HANA_NAMESPACE_BEGIN
|
||||
//! @ingroup group-core
|
||||
//! Create an object of the given tag with the given arguments.
|
||||
//!
|
||||
//! This function serves the same purpose as constructors in usual C++.
|
||||
//! However, instead of creating an object of a specific C++ type, it
|
||||
//! creates an object of a specific tag, regardless of the C++ type
|
||||
//! of that object.
|
||||
//!
|
||||
//! This function is actually a variable template, so `make<T>` can be
|
||||
//! passed around as a function object creating an object of tag `T`.
|
||||
//! Also, it uses tag-dispatching so this is how it should be customized
|
||||
//! for user-defined tags.
|
||||
//!
|
||||
//! Finally, the default implementation of `make` is equivalent to calling
|
||||
//! the constructor of the given tag with the corresponding arguments.
|
||||
//! In other words, by default,
|
||||
//! @code
|
||||
//! make<T>(args...) == T(args...)
|
||||
//! @endcode
|
||||
//!
|
||||
//! Note that the arguments are perfectly forwarded and the form of
|
||||
//! construction which is used is exactly as documented, i.e. `T(args...)`.
|
||||
//! However, if `T(args...)` is not a valid expression, a compilation
|
||||
//! error is triggered. This default behavior is useful because it makes
|
||||
//! foreign C++ types that have no notion of tag constructible with `make`
|
||||
//! out-of-the-box, since their tag is exactly themselves.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/make.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename Tag>
|
||||
constexpr auto make = [](auto&& ...x) -> decltype(auto) {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename Tag, typename = void>
|
||||
struct make_impl;
|
||||
|
||||
template <typename Tag>
|
||||
struct make_t {
|
||||
template <typename ...X>
|
||||
constexpr decltype(auto) operator()(X&& ...x) const {
|
||||
return make_impl<Tag>::apply(static_cast<X&&>(x)...);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Tag>
|
||||
constexpr make_t<Tag> make{};
|
||||
#endif
|
||||
BOOST_HANA_NAMESPACE_END
|
||||
|
||||
#endif // !BOOST_HANA_FWD_CORE_MAKE_HPP
|
||||
120
macx64/include/boost/hana/fwd/core/tag_of.hpp
Normal file
120
macx64/include/boost/hana/fwd/core/tag_of.hpp
Normal file
@@ -0,0 +1,120 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::tag_of` and `boost::hana::tag_of_t`.
|
||||
|
||||
@copyright Louis Dionne 2013-2017
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_FWD_CORE_TAG_OF_HPP
|
||||
#define BOOST_HANA_FWD_CORE_TAG_OF_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
BOOST_HANA_NAMESPACE_BEGIN
|
||||
//! @ingroup group-core
|
||||
//! %Metafunction returning the tag associated to `T`.
|
||||
//!
|
||||
//! There are several ways to specify the tag of a C++ type. If it's a
|
||||
//! user-defined type, one can define a nested `hana_tag` alias:
|
||||
//! @code
|
||||
//! struct MyUserDefinedType {
|
||||
//! using hana_tag = MyTag;
|
||||
//! };
|
||||
//! @endcode
|
||||
//!
|
||||
//! Sometimes, however, the C++ type can't be modified (if it's in a
|
||||
//! foreign library) or simply can't have nested types (if it's not a
|
||||
//! struct or class). In those cases, using a nested alias is impossible
|
||||
//! and so ad-hoc customization is also supported by specializing
|
||||
//! `tag_of` in the `boost::hana` namespace:
|
||||
//! @code
|
||||
//! struct i_cant_modify_this;
|
||||
//!
|
||||
//! namespace boost { namespace hana {
|
||||
//! template <>
|
||||
//! struct tag_of<i_cant_modify_this> {
|
||||
//! using type = MyTag;
|
||||
//! };
|
||||
//! }}
|
||||
//! @endcode
|
||||
//!
|
||||
//! `tag_of` can also be specialized for all C++ types satisfying some
|
||||
//! boolean condition using `when`. `when` accepts a single compile-time
|
||||
//! boolean and enables the specialization of `tag_of` if and only if
|
||||
//! that boolean is `true`. This is similar to the well known C++ idiom
|
||||
//! of using a dummy template parameter with `std::enable_if` and relying
|
||||
//! on SFINAE. For example, we could specify the tag of all
|
||||
//! `fusion::vector`s by doing:
|
||||
//! @code
|
||||
//! struct BoostFusionVector;
|
||||
//!
|
||||
//! namespace boost { namespace hana {
|
||||
//! template <typename T>
|
||||
//! struct tag_of<T, when<
|
||||
//! std::is_same<
|
||||
//! typename fusion::traits::tag_of<T>::type,
|
||||
//! fusion::traits::tag_of<fusion::vector<>>::type
|
||||
//! >::value
|
||||
//! >> {
|
||||
//! using type = BoostFusionVector;
|
||||
//! };
|
||||
//! }}
|
||||
//! @endcode
|
||||
//!
|
||||
//! Also, when it is not specialized and when the given C++ type does not
|
||||
//! have a nested `hana_tag` alias, `tag_of<T>` returns `T` itself. This
|
||||
//! makes tags a simple extension of normal C++ types. This is _super_
|
||||
//! useful, mainly for two reasons. First, this allows Hana to adopt a
|
||||
//! reasonable default behavior for some operations involving types that
|
||||
//! have no notion of tags. For example, Hana allows comparing with `equal`
|
||||
//! any two objects for which a valid `operator==` is defined, and that
|
||||
//! without any work on the user side. Second, it also means that you can
|
||||
//! ignore tags completely if you don't need their functionality; just use
|
||||
//! the normal C++ type of your objects and everything will "just work".
|
||||
//!
|
||||
//! Finally, also note that `tag_of<T>` is always equivalent to `tag_of<U>`,
|
||||
//! where `U` is the type `T` after being stripped of all references and
|
||||
//! cv-qualifiers. This makes it unnecessary to specialize `tag_of` for
|
||||
//! all reference and cv combinations, which would be a real pain. Also,
|
||||
//! `tag_of` is required to be idempotent. In other words, it must always
|
||||
//! be the case that `tag_of<tag_of<T>::%type>::%type` is equivalent to
|
||||
//! `tag_of<T>::%type`.
|
||||
//!
|
||||
//! > __Tip 1__\n
|
||||
//! > If compile-time performance is a serious concern, consider
|
||||
//! > specializing the `tag_of` metafunction in Hana's namespace.
|
||||
//! > When unspecialized, the metafunction has to use SFINAE, which
|
||||
//! > tends to incur a larger compile-time overhead. For heavily used
|
||||
//! > templated types, this can potentially make a difference.
|
||||
//!
|
||||
//! > __Tip 2__\n
|
||||
//! > Consider using `tag_of_t` alias instead of `tag_of`, which
|
||||
//! > reduces the amount of typing in dependent contexts.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/tag_of.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename T, optional when-based enabler>
|
||||
struct tag_of { unspecified };
|
||||
#else
|
||||
template <typename T, typename = void>
|
||||
struct tag_of;
|
||||
#endif
|
||||
|
||||
//! @ingroup group-core
|
||||
//! Alias to `tag_of<T>::%type`, provided for convenience.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/tag_of_t.cpp
|
||||
template <typename T>
|
||||
using tag_of_t = typename hana::tag_of<T>::type;
|
||||
BOOST_HANA_NAMESPACE_END
|
||||
|
||||
#endif // !BOOST_HANA_FWD_CORE_TAG_OF_HPP
|
||||
174
macx64/include/boost/hana/fwd/core/to.hpp
Normal file
174
macx64/include/boost/hana/fwd/core/to.hpp
Normal file
@@ -0,0 +1,174 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::to` and related utilities.
|
||||
|
||||
@copyright Louis Dionne 2013-2017
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_FWD_CORE_TO_HPP
|
||||
#define BOOST_HANA_FWD_CORE_TO_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
BOOST_HANA_NAMESPACE_BEGIN
|
||||
//! @ingroup group-core
|
||||
//! Converts an object from one data type to another.
|
||||
//!
|
||||
//! `to` is a natural extension of the `static_cast` language construct to
|
||||
//! data types. Given a destination data type `To` and an object `x`, `to`
|
||||
//! creates a new object of data type `To` from `x`. Note, however, that
|
||||
//! `to` is not required to actually create a new object, and may return a
|
||||
//! reference to the original object (for example when trying to convert
|
||||
//! an object to its own data type).
|
||||
//!
|
||||
//! As a natural extension to `static_cast`, `to` provides a default
|
||||
//! behavior. For the purpose of what follows, let `To` be the destination
|
||||
//! data type and `From` be the data type of `x`, i.e. the source data type.
|
||||
//! Then, `to` has the following default behavior:
|
||||
//! 1. If the `To` and `From` data types are the same, then the object
|
||||
//! is forwarded as-is.
|
||||
//! 2. Otherwise, if `From` is convertible to `To` using `static_cast`,
|
||||
//! `x` is converted to `From` using `static_cast`.
|
||||
//! 3. Otherwise, calling `to<From>(x)` triggers a static assertion.
|
||||
//!
|
||||
//! However, `to` is a tag-dispatched function, which means that `to_impl`
|
||||
//! may be specialized in the `boost::hana` namespace to customize its
|
||||
//! behavior for arbitrary data types. Also note that `to` is tag-dispatched
|
||||
//! using both the `To` and the `From` data types, which means that `to_impl`
|
||||
//! is called as `to_impl<To, From>::%apply(x)`. Also note that some
|
||||
//! concepts provide conversions to or from their models. For example,
|
||||
//! any `Foldable` may be converted into a `Sequence`. This is achieved
|
||||
//! by specializing `to_impl<To, From>` whenever `To` is a `Sequence` and
|
||||
//! `From` is a `Foldable`. When such conversions are provided, they are
|
||||
//! documented in the source concept, in this case `Foldable`.
|
||||
//!
|
||||
//!
|
||||
//! Hana-convertibility
|
||||
//! -------------------
|
||||
//! When an object `x` of data type `From` can be converted to a data type
|
||||
//! `To` using `to`, we say that `x` is Hana-convertible to the data type
|
||||
//! `To`. We also say that there is a Hana-conversion from `From` to `To`.
|
||||
//! This bit of terminology is useful to avoid mistaking the various kinds
|
||||
//! of conversions C++ offers.
|
||||
//!
|
||||
//!
|
||||
//! Embeddings
|
||||
//! ----------
|
||||
//! As you might have seen by now, Hana uses algebraic and category-
|
||||
//! theoretical structures all around the place to help specify concepts
|
||||
//! in a rigorous way. These structures always have operations associated
|
||||
//! to them, which is why they are useful. The notion of embedding captures
|
||||
//! the idea of injecting a smaller structure into a larger one while
|
||||
//! preserving the operations of the structure. In other words, an
|
||||
//! embedding is an injective mapping that is also structure-preserving.
|
||||
//! Exactly what it means for a structure's operations to be preserved is
|
||||
//! left to explain by the documentation of each structure. For example,
|
||||
//! when we talk of a Monoid-embedding from a Monoid `A` to a Monoid `B`,
|
||||
//! we simply mean an injective transformation that preserves the identity
|
||||
//! and the associative operation, as documented in `Monoid`.
|
||||
//!
|
||||
//! But what does this have to do with the `to` function? Quite simply,
|
||||
//! the `to` function is a mapping between two data types, which will
|
||||
//! sometimes be some kind of structure, and it is sometimes useful to
|
||||
//! know whether such a mapping is well-behaved, i.e. lossless and
|
||||
//! structure preserving. The criterion for this conversion to be well-
|
||||
//! behaved is exactly that of being an embedding. To specify that a
|
||||
//! conversion is an embedding, simply use the `embedding` type as a
|
||||
//! base class of the corresponding `to_impl` specialization. Obviously,
|
||||
//! you should make sure the conversion is really an embedding, unless
|
||||
//! you want to shoot yourself in the foot.
|
||||
//!
|
||||
//!
|
||||
//! @tparam To
|
||||
//! The data type to which `x` should be converted.
|
||||
//!
|
||||
//! @param x
|
||||
//! The object to convert to the given data type.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/convert/to.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename To>
|
||||
constexpr auto to = [](auto&& x) -> decltype(auto) {
|
||||
return tag-dispatched;
|
||||
};
|
||||
#else
|
||||
template <typename To, typename From, typename = void>
|
||||
struct to_impl;
|
||||
|
||||
template <typename To>
|
||||
struct to_t {
|
||||
template <typename X>
|
||||
constexpr decltype(auto) operator()(X&& x) const;
|
||||
};
|
||||
|
||||
template <typename To>
|
||||
constexpr to_t<To> to{};
|
||||
#endif
|
||||
|
||||
//! @ingroup group-core
|
||||
//! Returns whether there is a Hana-conversion from a data type to another.
|
||||
//!
|
||||
//! Specifically, `is_convertible<From, To>` is whether calling `to<To>`
|
||||
//! with an object of data type `From` would _not_ trigger a static
|
||||
//! assertion.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/convert/is_convertible.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename From, typename To>
|
||||
struct is_convertible { see documentation };
|
||||
#else
|
||||
template <typename From, typename To, typename = void>
|
||||
struct is_convertible;
|
||||
#endif
|
||||
|
||||
//! @ingroup group-core
|
||||
//! Marks a conversion between data types as being an embedding.
|
||||
//!
|
||||
//! To mark a conversion between two data types `To` and `From` as
|
||||
//! an embedding, simply use `embedding<true>` (or simply `embedding<>`)
|
||||
//! as a base class of the corresponding `to_impl` specialization.
|
||||
//! If a `to_impl` specialization does not inherit `embedding<true>`
|
||||
//! or `embedding<>`, then it is not considered an embedding by the
|
||||
//! `is_embedded` metafunction.
|
||||
//!
|
||||
//! > #### Tip
|
||||
//! > The boolean template parameter is useful for marking a conversion
|
||||
//! > as an embedding only when some condition is satisfied.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/convert/embedding.cpp
|
||||
template <bool = true>
|
||||
struct embedding { };
|
||||
|
||||
//! @ingroup group-core
|
||||
//! Returns whether a data type can be embedded into another data type.
|
||||
//!
|
||||
//! Given two data types `To` and `From`, `is_embedded<From, To>` returns
|
||||
//! whether `From` is convertible to `To`, and whether that conversion is
|
||||
//! also an embedding, as signaled by the `embedding` type.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/convert/is_embedded.cpp
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename From, typename To>
|
||||
struct is_embedded { see documentation };
|
||||
#else
|
||||
template <typename From, typename To, typename = void>
|
||||
struct is_embedded;
|
||||
#endif
|
||||
BOOST_HANA_NAMESPACE_END
|
||||
|
||||
#endif // !BOOST_HANA_FWD_CORE_TO_HPP
|
||||
74
macx64/include/boost/hana/fwd/core/when.hpp
Normal file
74
macx64/include/boost/hana/fwd/core/when.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/*!
|
||||
@file
|
||||
Forward declares `boost::hana::when` and `boost::hana::when_valid`.
|
||||
|
||||
@copyright Louis Dionne 2013-2017
|
||||
Distributed under the Boost Software License, Version 1.0.
|
||||
(See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
|
||||
*/
|
||||
|
||||
#ifndef BOOST_HANA_FWD_CORE_WHEN_HPP
|
||||
#define BOOST_HANA_FWD_CORE_WHEN_HPP
|
||||
|
||||
#include <boost/hana/config.hpp>
|
||||
|
||||
|
||||
BOOST_HANA_NAMESPACE_BEGIN
|
||||
//! @ingroup group-core
|
||||
//! Enable a partial specialization only if a boolean condition is true.
|
||||
//!
|
||||
//! You might also want to take a look at `when_valid`, which provides
|
||||
//! similar functionality but enables a specialziation only when some
|
||||
//! expression is well-formed.
|
||||
//!
|
||||
//! > #### Rationale for using `when` instead of `std::enable_if`
|
||||
//! > `when` is used to control the priority of partial specializations
|
||||
//! > in a finer grained manner than what can be achieved with the usual
|
||||
//! > `typename Enable = void` and `std::enable_if` pattern. For example,
|
||||
//! > a partially specialized tag-dispatched method will have a higher
|
||||
//! > priority than an equivalent specialization that uses `when`. For
|
||||
//! > more details, see the tutorial section on [tag-dispatching][1].
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/when.cpp
|
||||
//!
|
||||
//! [1]: @ref tutorial-core-tag_dispatching
|
||||
template <bool condition>
|
||||
struct when;
|
||||
|
||||
namespace core_detail {
|
||||
template <typename ...>
|
||||
struct always_true { static constexpr bool value = true; };
|
||||
}
|
||||
|
||||
//! @ingroup group-core
|
||||
//! Variant of `when` allowing specializations to be enabled only if an
|
||||
//! expression is well-formed.
|
||||
//!
|
||||
//! `when_valid<...>` is always equivalent to `when<true>`. However, when
|
||||
//! used inside a partial specialization, SFINAE will cause the partial
|
||||
//! specialization to be ignored when the expression is ill-formed.
|
||||
//!
|
||||
//!
|
||||
//! Example
|
||||
//! -------
|
||||
//! @include example/core/when_valid.cpp
|
||||
//!
|
||||
//!
|
||||
//! @bug
|
||||
//! Using `when_valid` seems to trigger ambiguous partial specializations
|
||||
//! on GCC.
|
||||
#ifdef BOOST_HANA_DOXYGEN_INVOKED
|
||||
template <typename ...>
|
||||
using when_valid = when<true>;
|
||||
#else
|
||||
template <typename ...Dummy>
|
||||
using when_valid = when<
|
||||
core_detail::always_true<Dummy...>::value
|
||||
>;
|
||||
#endif
|
||||
BOOST_HANA_NAMESPACE_END
|
||||
|
||||
#endif // !BOOST_HANA_FWD_CORE_WHEN_HPP
|
||||
Reference in New Issue
Block a user