add boost on mac

This commit is contained in:
Bassem Girgis
2019-08-10 16:38:17 -05:00
parent 861b918727
commit be945cb63b
14105 changed files with 2714968 additions and 0 deletions

View 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

View 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

View 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

View 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

View 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

View 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

View 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