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 38 template<class D> 39 char cdf(const D& ...); 40 template<class D> 41 char quantile(const D& ...); 42 43 template <class D> 44 struct has_cdf 45 { 46 static D d; 47 BOOST_STATIC_CONSTANT(bool, value = sizeof(cdf(d, 0.0f)) != 1); 48 }; 49 50 template <class D> 51 struct has_quantile 52 { 53 static D d; 54 BOOST_STATIC_CONSTANT(bool, value = sizeof(quantile(d, 0.0f)) != 1); 55 }; 56 57 template <class D> 58 struct is_distribution_imp 59 { 60 BOOST_STATIC_CONSTANT(bool, value = 61 has_quantile<D>::value 62 && has_cdf<D>::value 63 && has_value_type<D>::value 64 && has_policy_type<D>::value); 65 }; 66 67 template <class sig, sig val> 68 struct result_tag{}; 69 70 template <class D> 71 double test_has_location(const volatile result_tag<typename D::value_type (D::*)()const, &D::location>*); 72 template <class D> 73 char test_has_location(...); 74 75 template <class D> 76 double test_has_scale(const volatile result_tag<typename D::value_type (D::*)()const, &D::scale>*); 77 template <class D> 78 char test_has_scale(...); 79 80 template <class D, bool b> 81 struct is_scaled_distribution_helper 82 { 83 BOOST_STATIC_CONSTANT(bool, value = false); 84 }; 85 86 template <class D> 87 struct is_scaled_distribution_helper<D, true> 88 { 89 BOOST_STATIC_CONSTANT(bool, value = 90 (sizeof(test_has_location<D>(0)) != 1) 91 && 92 (sizeof(test_has_scale<D>(0)) != 1)); 93 }; 94 95 template <class D> 96 struct is_scaled_distribution_imp 97 { 98 BOOST_STATIC_CONSTANT(bool, value = (::boost::math::tools::detail::is_scaled_distribution_helper<D, ::boost::math::tools::detail::is_distribution_imp<D>::value>::value)); 99 }; 100 101 } // namespace detail 102 103 template <class T> struct is_distribution : public boost::integral_constant<bool, ::boost::math::tools::detail::is_distribution_imp<T>::value> {}; 104 template <class T> struct is_scaled_distribution : public boost::integral_constant<bool, ::boost::math::tools::detail::is_scaled_distribution_imp<T>::value> {}; 105 106 }}} 107 108 #endif 109 110 111