// Copyright John Maddock 2007. | |
// Use, modification and distribution are subject to the | |
// Boost Software License, Version 1.0. (See accompanying file | |
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
/* | |
This header defines two traits classes, both in namespace boost::math::tools. | |
is_distribution<D>::value is true iff D has overloaded "cdf" and | |
"quantile" functions, plus member typedefs value_type and policy_type. | |
It's not much of a definitive test frankly, | |
but if it looks like a distribution and quacks like a distribution | |
then it must be a distribution. | |
is_scaled_distribution<D>::value is true iff D is a distribution | |
as defined above, and has member functions "scale" and "location". | |
*/ | |
#ifndef BOOST_STATS_IS_DISTRIBUTION_HPP | |
#define BOOST_STATS_IS_DISTRIBUTION_HPP | |
#ifdef _MSC_VER | |
#pragma once | |
#endif | |
#include <boost/mpl/has_xxx.hpp> | |
// should be the last #include | |
#include <boost/type_traits/detail/bool_trait_def.hpp> | |
namespace boost{ namespace math{ namespace tools{ | |
namespace detail{ | |
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_value_type, value_type, true) | |
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(has_policy_type, policy_type, true) | |
template<class D> | |
char cdf(const D& ...); | |
template<class D> | |
char quantile(const D& ...); | |
template <class D> | |
struct has_cdf | |
{ | |
static D d; | |
BOOST_STATIC_CONSTANT(bool, value = sizeof(cdf(d, 0.0f)) != 1); | |
}; | |
template <class D> | |
struct has_quantile | |
{ | |
static D d; | |
BOOST_STATIC_CONSTANT(bool, value = sizeof(quantile(d, 0.0f)) != 1); | |
}; | |
template <class D> | |
struct is_distribution_imp | |
{ | |
BOOST_STATIC_CONSTANT(bool, value = | |
has_quantile<D>::value | |
&& has_cdf<D>::value | |
&& has_value_type<D>::value | |
&& has_policy_type<D>::value); | |
}; | |
template <class sig, sig val> | |
struct result_tag{}; | |
template <class D> | |
double test_has_location(const volatile result_tag<typename D::value_type (D::*)()const, &D::location>*); | |
template <class D> | |
char test_has_location(...); | |
template <class D> | |
double test_has_scale(const volatile result_tag<typename D::value_type (D::*)()const, &D::scale>*); | |
template <class D> | |
char test_has_scale(...); | |
template <class D, bool b> | |
struct is_scaled_distribution_helper | |
{ | |
BOOST_STATIC_CONSTANT(bool, value = false); | |
}; | |
template <class D> | |
struct is_scaled_distribution_helper<D, true> | |
{ | |
BOOST_STATIC_CONSTANT(bool, value = | |
(sizeof(test_has_location<D>(0)) != 1) | |
&& | |
(sizeof(test_has_scale<D>(0)) != 1)); | |
}; | |
template <class D> | |
struct is_scaled_distribution_imp | |
{ | |
BOOST_STATIC_CONSTANT(bool, value = (::boost::math::tools::detail::is_scaled_distribution_helper<D, ::boost::math::tools::detail::is_distribution_imp<D>::value>::value)); | |
}; | |
} // namespace detail | |
BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_distribution,T,::boost::math::tools::detail::is_distribution_imp<T>::value) | |
BOOST_TT_AUX_BOOL_TRAIT_DEF1(is_scaled_distribution,T,::boost::math::tools::detail::is_scaled_distribution_imp<T>::value) | |
}}} | |
#endif | |