diff options
Diffstat (limited to 'boost/hana/one.hpp')
-rw-r--r-- | boost/hana/one.hpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/boost/hana/one.hpp b/boost/hana/one.hpp new file mode 100644 index 0000000000..47b902da60 --- /dev/null +++ b/boost/hana/one.hpp @@ -0,0 +1,79 @@ +/*! +@file +Defines `boost::hana::one`. + +@copyright Louis Dionne 2013-2016 +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_ONE_HPP +#define BOOST_HANA_ONE_HPP + +#include <boost/hana/fwd/one.hpp> + +#include <boost/hana/concept/constant.hpp> +#include <boost/hana/concept/ring.hpp> +#include <boost/hana/config.hpp> +#include <boost/hana/core/to.hpp> +#include <boost/hana/core/dispatch.hpp> +#include <boost/hana/detail/canonical_constant.hpp> + +#include <type_traits> + + +BOOST_HANA_NAMESPACE_BEGIN + template <typename R> + struct one_t { + #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS + static_assert(hana::Ring<R>::value, + "hana::one<R>() requires 'R' to be a Ring"); + #endif + + constexpr decltype(auto) operator()() const { + using One = BOOST_HANA_DISPATCH_IF(one_impl<R>, + hana::Ring<R>::value + ); + + return One::apply(); + } + }; + + template <typename R, bool condition> + struct one_impl<R, when<condition>> : default_ { + template <typename ...Args> + static constexpr auto apply(Args&& ...) = delete; + }; + + ////////////////////////////////////////////////////////////////////////// + // Model for non-boolean arithmetic data types + ////////////////////////////////////////////////////////////////////////// + template <typename T> + struct one_impl<T, when<std::is_arithmetic<T>::value && + !std::is_same<bool, T>::value>> { + static constexpr T apply() + { return static_cast<T>(1); } + }; + + ////////////////////////////////////////////////////////////////////////// + // Model for Constants over a Ring + ////////////////////////////////////////////////////////////////////////// + namespace detail { + template <typename C> + struct constant_from_one { + static constexpr auto value = hana::one<typename C::value_type>(); + using hana_tag = detail::CanonicalConstant<typename C::value_type>; + }; + } + + template <typename C> + struct one_impl<C, when< + hana::Constant<C>::value && + Ring<typename C::value_type>::value + >> { + static constexpr decltype(auto) apply() + { return hana::to<C>(detail::constant_from_one<C>{}); } + }; +BOOST_HANA_NAMESPACE_END + +#endif // !BOOST_HANA_ONE_HPP |