// The MIT License (MIT) // // Copyright (c) 2018 Bruno Dutra // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. #ifndef METAL_HPP #define METAL_HPP #ifndef METAL_CONFIG_HPP #define METAL_CONFIG_HPP #ifndef METAL_CONFIG_CONFIG_HPP #define METAL_CONFIG_CONFIG_HPP #if !defined(METAL_WORKAROUND) #if (defined(__GNUC__) && !defined(__clang__) && (__GNUC__ < 5)) || (defined(_MSC_VER) && !defined(__clang__)) #define METAL_WORKAROUND #endif #endif #endif #ifndef METAL_CONFIG_VERSION_HPP #define METAL_CONFIG_VERSION_HPP /// \ingroup config /// /// ### Description /// Expands to the major version of Metal. /// /// ### See Also /// \see [Semantic Versioning](http://semver.org/) #define METAL_MAJOR 2 /// \ingroup config /// /// ### Description /// Expands to the minor version of Metal. /// /// ### See Also /// \see [Semantic Versioning](http://semver.org/) #define METAL_MINOR 1 /// \ingroup config /// /// ### Description /// Expands to the patch version of Metal. /// /// ### See Also /// \see [Semantic Versioning](http://semver.org/) #define METAL_PATCH 4 /// \ingroup config /// \hideinitializer /// /// ### Description /// Given a `{major, minor, patch}` triple, expands to an implementation defined /// integral constant that is guaranteed to be comparable according to /// [Semantic Versioning](http://semver.org/) rules. /// /// ### See Also /// \see [Semantic Versioning](http://semver.org/) #define METAL_SEMVER(MAJOR, MINOR, PATCH) (((MAJOR)*1000000) + ((MINOR)*10000) + (PATCH)) /// \ingroup config /// Expands to the full version of Metal. /// /// ### See Also /// \see [Semantic Versioning](http://semver.org/) #define METAL_VERSION METAL_SEMVER(METAL_MAJOR, METAL_MINOR, METAL_PATCH) #endif /// \defgroup config Config /// \ingroup metal #endif #ifndef METAL_LAMBDA_HPP #define METAL_LAMBDA_HPP #ifndef METAL_LAMBDA_ALWAYS_HPP #define METAL_LAMBDA_ALWAYS_HPP namespace metal { /// \cond namespace detail { template struct _always; } /// \endcond /// \ingroup lambda /// /// ### Description /// Lifts a \value to an n-ary \lambda that always evaluates to that \value, /// regardless of the argument(s) it's [invoked](\ref invoke) with. /// /// ### Usage /// For any and \value `val` /// \code /// using result = metal::always; /// \endcode /// /// \returns: \lambda /// \semantics: /// Equivalent to /// \code /// using result = metal::lambda; /// \endcode /// where `expr` is an \expression such that /// \code /// template /// using expr = val; /// \endcode /// /// ### Example /// \snippet lambda.cpp always /// /// ### See Also /// \see lambda, invoke, partial, bind template using always = typename detail::_always::type; } #ifndef METAL_LAMBDA_LAMBDA_HPP #define METAL_LAMBDA_LAMBDA_HPP namespace metal { /// \cond namespace detail { template struct _is_lambda; template struct _as_lambda; } /// \endcond /// \ingroup lambda /// /// ### Description /// Checks whether some \value is a \lambda. /// /// ### Usage /// For any \value `val` /// \code /// using result = metal::is_lambda; /// \endcode /// /// \returns: \number /// \semantics: /// If `val` is a \lambda, then /// \code /// using result = metal::true_; /// \endcode /// otherwise /// \code /// using result = metal::false_; /// \endcode /// /// ### Example /// \snippet lambda.cpp is_lambda /// /// ### See Also /// \see lambda, is_value, is_number, is_pair, is_list, is_map template using is_lambda = typename detail::_is_lambda::type; /// \ingroup lambda /// /// ### Description /// Given any \value that is a specialization of a template class or union /// whose template parameters are all themselves \values, constructs a /// \lambda that contains that template. /// /// ### Usage /// For any \value `val` /// \code /// using result = metal::as_lambda; /// \endcode /// /// \returns: \lambda /// /// ### Example /// \snippet lambda.cpp as_lambda /// /// ### See Also /// \see lambda, as_list template using as_lambda = typename detail::_as_lambda::type; /// \ingroup lambda /// /// ### Description /// Constructs a \lambda out of an \expression. /// /// ### Usage /// For any \expression `expr` /// \code /// using result = metal::lambda; /// \endcode /// /// \returns: \lambda /// /// ### See Also /// \see is_lambda template