Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make real concept constexpr #942

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
116 changes: 58 additions & 58 deletions include/boost/math/concepts/real_concept.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,106 +60,106 @@ class real_concept
{
public:
// Constructors:
real_concept() : m_value(0){}
real_concept(char c) : m_value(c){}
real_concept(wchar_t c) : m_value(c){}
real_concept(unsigned char c) : m_value(c){}
real_concept(signed char c) : m_value(c){}
real_concept(unsigned short c) : m_value(c){}
real_concept(short c) : m_value(c){}
real_concept(unsigned int c) : m_value(c){}
real_concept(int c) : m_value(c){}
real_concept(unsigned long c) : m_value(c){}
real_concept(long c) : m_value(c){}
real_concept(unsigned long long c) : m_value(static_cast<real_concept_base_type>(c)){}
real_concept(long long c) : m_value(static_cast<real_concept_base_type>(c)){}
real_concept(float c) : m_value(c){}
real_concept(double c) : m_value(c){}
real_concept(long double c) : m_value(c){}
constexpr real_concept() : m_value(0){}
constexpr real_concept(char c) : m_value(c){}
constexpr real_concept(wchar_t c) : m_value(c){}
constexpr real_concept(unsigned char c) : m_value(c){}
constexpr real_concept(signed char c) : m_value(c){}
constexpr real_concept(unsigned short c) : m_value(c){}
constexpr real_concept(short c) : m_value(c){}
constexpr real_concept(unsigned int c) : m_value(c){}
constexpr real_concept(int c) : m_value(c){}
constexpr real_concept(unsigned long c) : m_value(c){}
constexpr real_concept(long c) : m_value(c){}
constexpr real_concept(unsigned long long c) : m_value(static_cast<real_concept_base_type>(c)){}
constexpr real_concept(long long c) : m_value(static_cast<real_concept_base_type>(c)){}
constexpr real_concept(float c) : m_value(c){}
constexpr real_concept(double c) : m_value(c){}
constexpr real_concept(long double c) : m_value(c){}
#ifdef BOOST_MATH_USE_FLOAT128
real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){}
constexpr real_concept(BOOST_MATH_FLOAT128_TYPE c) : m_value(c){}
#endif

// Assignment:
real_concept& operator=(char c) { m_value = c; return *this; }
real_concept& operator=(unsigned char c) { m_value = c; return *this; }
real_concept& operator=(signed char c) { m_value = c; return *this; }
real_concept& operator=(wchar_t c) { m_value = c; return *this; }
real_concept& operator=(short c) { m_value = c; return *this; }
real_concept& operator=(unsigned short c) { m_value = c; return *this; }
real_concept& operator=(int c) { m_value = c; return *this; }
real_concept& operator=(unsigned int c) { m_value = c; return *this; }
real_concept& operator=(long c) { m_value = c; return *this; }
real_concept& operator=(unsigned long c) { m_value = c; return *this; }
real_concept& operator=(long long c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
real_concept& operator=(unsigned long long c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
real_concept& operator=(float c) { m_value = c; return *this; }
real_concept& operator=(double c) { m_value = c; return *this; }
real_concept& operator=(long double c) { m_value = c; return *this; }
constexpr real_concept& operator=(char c) { m_value = c; return *this; }
constexpr real_concept& operator=(unsigned char c) { m_value = c; return *this; }
constexpr real_concept& operator=(signed char c) { m_value = c; return *this; }
constexpr real_concept& operator=(wchar_t c) { m_value = c; return *this; }
constexpr real_concept& operator=(short c) { m_value = c; return *this; }
constexpr real_concept& operator=(unsigned short c) { m_value = c; return *this; }
constexpr real_concept& operator=(int c) { m_value = c; return *this; }
constexpr real_concept& operator=(unsigned int c) { m_value = c; return *this; }
constexpr real_concept& operator=(long c) { m_value = c; return *this; }
constexpr real_concept& operator=(unsigned long c) { m_value = c; return *this; }
constexpr real_concept& operator=(long long c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
constexpr real_concept& operator=(unsigned long long c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
constexpr real_concept& operator=(float c) { m_value = c; return *this; }
constexpr real_concept& operator=(double c) { m_value = c; return *this; }
constexpr real_concept& operator=(long double c) { m_value = c; return *this; }

// Access:
real_concept_base_type value()const{ return m_value; }
constexpr real_concept_base_type value()const{ return m_value; }

// Member arithmetic:
real_concept& operator+=(const real_concept& other)
constexpr real_concept& operator+=(const real_concept& other)
{ m_value += other.value(); return *this; }
real_concept& operator-=(const real_concept& other)
constexpr real_concept& operator-=(const real_concept& other)
{ m_value -= other.value(); return *this; }
real_concept& operator*=(const real_concept& other)
constexpr real_concept& operator*=(const real_concept& other)
{ m_value *= other.value(); return *this; }
real_concept& operator/=(const real_concept& other)
constexpr real_concept& operator/=(const real_concept& other)
{ m_value /= other.value(); return *this; }
real_concept operator-()const
constexpr real_concept operator-()const
{ return -m_value; }
real_concept const& operator+()const
constexpr real_concept const& operator+()const
{ return *this; }
real_concept& operator++()
constexpr real_concept& operator++()
{ ++m_value; return *this; }
real_concept& operator--()
constexpr real_concept& operator--()
{ --m_value; return *this; }

private:
real_concept_base_type m_value;
};

// Non-member arithmetic:
inline real_concept operator+(const real_concept& a, const real_concept& b)
constexpr real_concept operator+(const real_concept& a, const real_concept& b)
{
real_concept result(a);
result += b;
return result;
}
inline real_concept operator-(const real_concept& a, const real_concept& b)
constexpr real_concept operator-(const real_concept& a, const real_concept& b)
{
real_concept result(a);
result -= b;
return result;
}
inline real_concept operator*(const real_concept& a, const real_concept& b)
constexpr real_concept operator*(const real_concept& a, const real_concept& b)
{
real_concept result(a);
result *= b;
return result;
}
inline real_concept operator/(const real_concept& a, const real_concept& b)
constexpr real_concept operator/(const real_concept& a, const real_concept& b)
{
real_concept result(a);
result /= b;
return result;
}

// Comparison:
inline bool operator == (const real_concept& a, const real_concept& b)
constexpr bool operator == (const real_concept& a, const real_concept& b)
{ return a.value() == b.value(); }
inline bool operator != (const real_concept& a, const real_concept& b)
constexpr bool operator != (const real_concept& a, const real_concept& b)
{ return a.value() != b.value();}
inline bool operator < (const real_concept& a, const real_concept& b)
constexpr bool operator < (const real_concept& a, const real_concept& b)
{ return a.value() < b.value(); }
inline bool operator <= (const real_concept& a, const real_concept& b)
constexpr bool operator <= (const real_concept& a, const real_concept& b)
{ return a.value() <= b.value(); }
inline bool operator > (const real_concept& a, const real_concept& b)
constexpr bool operator > (const real_concept& a, const real_concept& b)
{ return a.value() > b.value(); }
inline bool operator >= (const real_concept& a, const real_concept& b)
constexpr bool operator >= (const real_concept& a, const real_concept& b)
{ return a.value() >= b.value(); }

// Non-member functions:
Expand Down Expand Up @@ -319,37 +319,37 @@ namespace tools
{

template <>
inline concepts::real_concept make_big_value<concepts::real_concept>(boost::math::tools::largest_float val, const char* , std::false_type const&, std::false_type const&)
constexpr concepts::real_concept make_big_value<concepts::real_concept>(boost::math::tools::largest_float val, const char* , std::false_type const&, std::false_type const&)
{
return val; // Can't use lexical_cast here, sometimes it fails....
}

template <>
inline concepts::real_concept max_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
constexpr concepts::real_concept max_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
{
return max_value<concepts::real_concept_base_type>();
}

template <>
inline concepts::real_concept min_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
constexpr concepts::real_concept min_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
{
return min_value<concepts::real_concept_base_type>();
}

template <>
inline concepts::real_concept log_max_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
constexpr concepts::real_concept log_max_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
{
return log_max_value<concepts::real_concept_base_type>();
}

template <>
inline concepts::real_concept log_min_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
constexpr concepts::real_concept log_min_value<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
{
return log_min_value<concepts::real_concept_base_type>();
}

template <>
inline concepts::real_concept epsilon<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
constexpr concepts::real_concept epsilon<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept))
{
#ifdef __SUNPRO_CC
return std::numeric_limits<concepts::real_concept_base_type>::epsilon();
Expand All @@ -359,7 +359,7 @@ inline concepts::real_concept epsilon<concepts::real_concept>(BOOST_MATH_EXPLICI
}

template <>
inline constexpr int digits<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) noexcept
constexpr int digits<concepts::real_concept>(BOOST_MATH_EXPLICIT_TEMPLATE_TYPE_SPEC(concepts::real_concept)) noexcept
{
// Assume number of significand bits is same as real_concept_base_type,
// unless std::numeric_limits<T>::is_specialized to provide digits.
Expand Down
1 change: 1 addition & 0 deletions test/Jamfile.v2
Original file line number Diff line number Diff line change
Expand Up @@ -1204,6 +1204,7 @@ test-suite misc :
[ compile bernoulli_no_atomic_d.cpp ]
[ compile bernoulli_no_atomic_mp.cpp ]
[ compile-fail bernoulli_no_atomic_fail.cpp ]
[ run test_constexpr_real_concept.cpp ]
;

test-suite interpolators :
Expand Down
26 changes: 26 additions & 0 deletions test/test_constexpr_real_concept.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// (C) Copyright Matt Borland 2023.
// 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)

#include <boost/math/concepts/real_concept.hpp>

int main(void)
{
using namespace boost::math::concepts;

constexpr real_concept val1(1.0);
constexpr real_concept val2(2.0);

// Member functions
static_assert(val1 < val2, "val1 should be less than val2");
static_assert(val1 + val2 >= 2.999L, "Addition is 3");
static_assert(val1 * val2 >= 1.999L, "Multiplication is 2");
static_assert(val2 / val1 >= 1.999L, "Division is 2");

// Tools
static_assert(boost::math::tools::max_value<real_concept>() > 0, "max value");
static_assert(boost::math::tools::min_value<real_concept>() > 0, "min value");
static_assert(boost::math::tools::epsilon<real_concept>() > 0, "Epsilon");
static_assert(boost::math::tools::digits<real_concept>() > 0, "Digits");
}