On 12/03/2017 15:56, Robert Ramey via Boost wrote:
On 3/12/17 7:54 AM, Peter Dimov via Boost wrote:
John Maddock wrote:
5) What is the purpose of class safe_literal? constepxr initialization seems to work just fine without it?
The idea, I believe, is that if you have
safe_signed_range<0, 100> x;
and then you do
auto y = x * safe_signed_literal<2>();
you get safe_signed_range<0, 200> as the type of y. This could probably be made less elaborate with a user-defined literal, for example
auto y = x * 2_sf;
or something like that.
That would be my preferred solution - to define a user-defined suffix, so that: 4_safe is a literal of type safe_signed_range<4,4>. No need for safe_literal here IMO?
Since x is not constexpr, it's not possible (I think) to achieve this result without using a separate literal type to hold the compile-time constant 2.
here is the problem:
constexpr int i = 42; // i is constexpr and available at compile time constexpr const safe_int x(i); // x is constexpr and available at compile time
constexpr const safe_int y(42); // y is NOT available at compile time!!!
Oh yes it is!
There is nothing at all non-constexpr about integer literals. Consider
the following toy class, that restricts values to the range [-10,10], it
performs runtime checking just like your safe class does, and still
works in constexpr:
class ten
{
private:
int m_value;
public:
template <class I>
constexpr ten(I i) : m_value(i)
{
if (i > 10 || i < -10)
throw std::overflow_error("Expected value excedes +-10");
}
constexpr ten(const ten& a) : m_value(a.m_value) {}
constexpr ten& operator += (const ten& i)
{
if ((i.m_value > 0) && (m_value > 0) && (10 - m_value < i.m_value))
throw std::overflow_error("Addition results in value > 10");
if ((i.m_value < 0) && (m_value < 0) && (10 + m_value > i.m_value))
throw std::overflow_error("Addition results in a value < 10");
return *this;
}
explicit constexpr operator int()const { return m_value; }
};
constexpr ten operator+(const ten& i, const ten& b)
{
ten result(i);
return result += b;
}
Now given:
template <int value>
struct ten_holder {};
we can write:
const constexpr ten i(5);
const constexpr ten j(5);
const constexpr ten k = j + i;
ten_holder
constexpr const safe_int z(safe_signed_literal<42>()); // z is NOW available at compile
So the problem is that literals are not considered constexpr. I believe this is a problem is with the way constexpr is defined.
Actually I have a whole rant on constexpr and const expressions. I believe that C++ standard has made this a lot more complex and less useful than it could be. But I can pursue only one hopeless quest at at time.
Robert Ramey
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost .
--- This email has been checked for viruses by AVG. http://www.avg.com