1 /*! 2 @file 3 Defines `boost::hana::zero`. 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_ZERO_HPP 11 #define BOOST_HANA_ZERO_HPP 12 13 #include <boost/hana/fwd/zero.hpp> 14 15 #include <boost/hana/concept/constant.hpp> 16 #include <boost/hana/concept/monoid.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 M> operator ()() const28 constexpr decltype(auto) zero_t<M>::operator()() const { 29 #ifndef BOOST_HANA_CONFIG_DISABLE_CONCEPT_CHECKS 30 static_assert(hana::Monoid<M>::value, 31 "hana::zero<M>() requires 'M' to be a Monoid"); 32 #endif 33 34 using Zero = BOOST_HANA_DISPATCH_IF(zero_impl<M>, 35 hana::Monoid<M>::value 36 ); 37 38 return Zero::apply(); 39 } 40 //! @endcond 41 42 template <typename M, bool condition> 43 struct zero_impl<M, 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 zero_impl<T, when< 53 std::is_arithmetic<T>::value && 54 !std::is_same<T, bool>::value 55 >> { applyzero_impl56 static constexpr T apply() 57 { return static_cast<T>(0); } 58 }; 59 60 ////////////////////////////////////////////////////////////////////////// 61 // Model for Constants over a Monoid 62 ////////////////////////////////////////////////////////////////////////// 63 namespace detail { 64 template <typename C> 65 struct constant_from_zero { 66 static constexpr auto value = hana::zero<typename C::value_type>(); 67 using hana_tag = detail::CanonicalConstant<typename C::value_type>; 68 }; 69 } 70 71 template <typename C> 72 struct zero_impl<C, when< 73 hana::Constant<C>::value && 74 Monoid<typename C::value_type>::value 75 >> { applyzero_impl76 static constexpr decltype(auto) apply() 77 { return hana::to<C>(detail::constant_from_zero<C>{}); } 78 }; 79 BOOST_HANA_NAMESPACE_END 80 81 #endif // !BOOST_HANA_ZERO_HPP 82