1 // Copyright John Maddock 2007. 2 3 // Use, modification and distribution are subject to the 4 // Boost Software License, Version 1.0. (See accompanying file 5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 7 /* 8 This header defines two traits classes, both in namespace boost::math::tools. 9 10 is_distribution<D>::value is true iff D has overloaded "cdf" and 11 "quantile" functions, plus member typedefs value_type and policy_type. 12 It's not much of a definitive test frankly, 13 but if it looks like a distribution and quacks like a distribution 14 then it must be a distribution. 15 16 is_scaled_distribution<D>::value is true iff D is a distribution 17 as defined above, and has member functions "scale" and "location". 18 19 */ 20 21 #ifndef BOOST_STATS_IS_DISTRIBUTION_HPP 22 #define BOOST_STATS_IS_DISTRIBUTION_HPP 23 24 #ifdef _MSC_VER 25 #pragma once 26 #endif 27 28 #include <boost/mpl/has_xxx.hpp> 29 #include <boost/type_traits/integral_constant.hpp> 30 31 namespace boost{ namespace math{ namespace tools{ 32 33 namespace detail{ 34 35 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_value_type, value_type, true) 36 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_policy_type, policy_type, true) 37 BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_backend_type, backend_type, true) 38 39 template<class D> 40 char cdf(const D& ...); 41 template<class D> 42 char quantile(const D& ...); 43 44 template <class D> 45 struct has_cdf 46 { 47 static D d; 48 BOOST_STATIC_CONSTANT(bool, value = sizeof(cdf(d, 0.0f)) != 1); 49 }; 50 51 template <class D> 52 struct has_quantile 53 { 54 static D d; 55 BOOST_STATIC_CONSTANT(bool, value = sizeof(quantile(d, 0.0f)) != 1); 56 }; 57 58 template <class D> 59 struct is_distribution_imp 60 { 61 BOOST_STATIC_CONSTANT(bool, value = 62 has_quantile<D>::value 63 && has_cdf<D>::value 64 && has_value_type<D>::value 65 && has_policy_type<D>::value); 66 }; 67 68 template <class sig, sig val> 69 struct result_tag{}; 70 71 template <class D> 72 double test_has_location(const volatile result_tag<typename D::value_type (D::*)()const, &D::location>*); 73 template <class D> 74 char test_has_location(...); 75 76 template <class D> 77 double test_has_scale(const volatile result_tag<typename D::value_type (D::*)()const, &D::scale>*); 78 template <class D> 79 char test_has_scale(...); 80 81 template <class D, bool b> 82 struct is_scaled_distribution_helper 83 { 84 BOOST_STATIC_CONSTANT(bool, value = false); 85 }; 86 87 template <class D> 88 struct is_scaled_distribution_helper<D, true> 89 { 90 BOOST_STATIC_CONSTANT(bool, value = 91 (sizeof(test_has_location<D>(0)) != 1) 92 && 93 (sizeof(test_has_scale<D>(0)) != 1)); 94 }; 95 96 template <class D> 97 struct is_scaled_distribution_imp 98 { 99 BOOST_STATIC_CONSTANT(bool, value = (::boost::math::tools::detail::is_scaled_distribution_helper<D, ::boost::math::tools::detail::is_distribution_imp<D>::value>::value)); 100 }; 101 102 } // namespace detail 103 104 template <class T> struct is_distribution : public boost::integral_constant<bool, ::boost::math::tools::detail::is_distribution_imp<T>::value> {}; 105 template <class T> struct is_scaled_distribution : public boost::integral_constant<bool, ::boost::math::tools::detail::is_scaled_distribution_imp<T>::value> {}; 106 107 }}} 108 109 #endif 110 111 112