//=================================================================================================

//=================================================================================================

#ifndef _BLAZE_UTIL_CONSTRAINTS_NUMERIC_H_
#define _BLAZE_UTIL_CONSTRAINTS_NUMERIC_H_


//*************************************************************************************************
// Includes
//*************************************************************************************************

#include <blaze/util/constraints/ConstraintTest.h>
#include <blaze/util/Suffix.h>
#include <blaze/util/typetraits/IsNumeric.h>


namespace blaze {

//=================================================================================================
//
//  MUST_BE_NUMERIC_TYPE CONSTRAINT
//
//=================================================================================================

//*************************************************************************************************
/*! \cond BLAZE_INTERNAL */
/*!\brief Compile time constraint.
// \ingroup constraints
//
// Helper template class for the compile time constraint enforcement. Based on the compile time
// constant expression used for the template instantiation, either the undefined basic template
// or the specialization is selected. If the undefined basic template is selected, a compilation
// error is created.
*/
template< bool > struct CONSTRAINT_MUST_BE_NUMERIC_TYPE_FAILED;
template<> struct CONSTRAINT_MUST_BE_NUMERIC_TYPE_FAILED<true> { enum { value = 1 }; };
/*! \endcond */
//*************************************************************************************************


//*************************************************************************************************
/*!\brief Constraint on the data type.
// \ingroup constraints
//
// In case the given data type \a T is not a numeric (integral or floating point) data type,
// a compilation error is created.
*/
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T) \
   typedef \
      ::blaze::CONSTRAINT_TEST< \
         ::blaze::CONSTRAINT_MUST_BE_NUMERIC_TYPE_FAILED< ::blaze::IsNumeric<T>::value >::value > \
      BLAZE_JOIN( CONSTRAINT_MUST_BE_NUMERIC_TYPE_TYPEDEF, __LINE__ )
//*************************************************************************************************




//=================================================================================================
//
//  MUST_NOT_BE_NUMERIC_TYPE CONSTRAINT
//
//=================================================================================================

//*************************************************************************************************
/*! \cond BLAZE_INTERNAL */
/*!\brief Compile time constraint.
// \ingroup constraints
//
// Helper template class for the compile time constraint enforcement. Based on the compile time
// constant expression used for the template instantiation, either the undefined basic template
// or the specialization is selected. If the undefined basic template is selected, a compilation
// error is created.
*/
template< bool > struct CONSTRAINT_MUST_NOT_BE_NUMERIC_TYPE_FAILED;
template<> struct CONSTRAINT_MUST_NOT_BE_NUMERIC_TYPE_FAILED<true> { enum { value = 1 }; };
/*! \endcond */
//*************************************************************************************************


//*************************************************************************************************
/*!\brief Constraint on the data type.
// \ingroup constraints
//
// In case the given data type \a T is a numeric (integral or floating point) data type,
// a compilation error is created.
*/
#define BLAZE_CONSTRAINT_MUST_NOT_BE_NUMERIC_TYPE(T) \
   typedef \
      ::blaze::CONSTRAINT_TEST< \
         ::blaze::CONSTRAINT_MUST_NOT_BE_NUMERIC_TYPE_FAILED< ::blaze::IsNumeric<T>::value >::value > \
      BLAZE_JOIN( CONSTRAINT_MUST_NOT_BE_NUMERIC_TYPE_TYPEDEF, __LINE__ )
//*************************************************************************************************

} // namespace blaze

#endif
