1 /*! 2 @file 3 Defines `boost::hana::one`. 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_ONE_HPP 11 #define BOOST_HANA_ONE_HPP 12 13 #include <boost/hana/fwd/one.hpp> 14 15 #include <boost/hana/concept/constant.hpp> 16 #include <boost/hana/concept/ring.hpp> 17 #include <boost/hana/config.hpp> 18 #include <boost/hana/core/to.hpp> 19 #include <boost/hana/core/dispatch.hpp> 20 #include <boost/hana/detail/canonical_constant.hpp> 21 22 #include <type_traits> 23 24 25 BOOST_HANA_NAMESPACE_BEGIN 26 //! @cond 27 template <typename R> operator ()() const28 constexpr decltype(auto) one_t<R>::operator()() const { 29 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS 30 static_assert(hana::Ring<R>::value, 31 "hana::one<R>() requires 'R' to be a Ring"); 32 #endif 33 34 using One = BOOST_HANA_DISPATCH_IF(one_impl<R>, 35 hana::Ring<R>::value 36 ); 37 38 return One::apply(); 39 } 40 //! @endcond 41 42 template <typename R, bool condition> 43 struct one_impl<R, when<condition>> : default_ { 44 template <typename ...Args> 45 static constexpr auto apply(Args&& ...) = delete; 46 }; 47 48 ////////////////////////////////////////////////////////////////////////// 49 // Model for non-boolean arithmetic data types 50 ////////////////////////////////////////////////////////////////////////// 51 template <typename T> 52 struct one_impl<T, when<std::is_arithmetic<T>::value && 53 !std::is_same<bool, T>::value>> { applyone_impl54 static constexpr T apply() 55 { return static_cast<T>(1); } 56 }; 57 58 ////////////////////////////////////////////////////////////////////////// 59 // Model for Constants over a Ring 60 ////////////////////////////////////////////////////////////////////////// 61 namespace detail { 62 template <typename C> 63 struct constant_from_one { 64 static constexpr auto value = hana::one<typename C::value_type>(); 65 using hana_tag = detail::CanonicalConstant<typename C::value_type>; 66 }; 67 } 68 69 template <typename C> 70 struct one_impl<C, when< 71 hana::Constant<C>::value && 72 Ring<typename C::value_type>::value 73 >> { applyone_impl74 static constexpr decltype(auto) apply() 75 { return hana::to<C>(detail::constant_from_one<C>{}); } 76 }; 77 BOOST_HANA_NAMESPACE_END 78 79 #endif // !BOOST_HANA_ONE_HPP 80