Boost logo

Boost :

Subject: Re: [boost] Boost.Exception and constexpr
From: Vicente J. Botet Escriba (vicente.botet_at_[hidden])
Date: 2013-01-10 02:37:19


Le 10/01/13 07:44, Emil Dotchevski a écrit :
> On Wed, Jan 9, 2013 at 6:23 PM, Marshall Clow <mclow.lists_at_[hidden]> wrote:
>> Has anyone put any effort into making Boost.Exception (and BOOST_ASSERT) work with constexpr?
> I don't think assert or throw are compatible with constexpr.
>
>
I don't see a problem with throw. The problem is with throw_exception.
We can add a basic_throw_exception that behaves as the old
throw_exception that can be made constexpr

#ifdef BOOST_NO_EXCEPTIONS

BOOST_CONTEXPR void basic_throw_exception( std::exception const & e );
// user defined

#else

inline BOOST_CONTEXPR bool basic_throw_exception_assert_compatibility(
std::exception const & ) { return true; }

template<class E> BOOST_ATTRIBUTE_NORETURN inline BOOST_CONTEXPR void
basic_throw_exception( E const & e )
{
     //All boost exceptions are required to derive from std::exception,
     //to ensure compatibility with BOOST_NO_EXCEPTIONS.
     if (basic_throw_exception_assert_compatibility(e))
       throw e;
     else
       throw e;
}

#endif

so that rangecheck is constexpr

         static BOOST_CONTTEXPR void rangecheck (size_type i) {
             if (i >= size())
                 basic_throw_exception( std::out_of_range e("array<>: index out of range") );
             }

On the other side, assert is a C macro so no way to qualify it as constexpr.

The best we can do instead of asserting

         const_reference operator[](size_type i) const
         {
             BOOST_ASSERT_MSG( i < N, "out of range" );
             return elems[i];
         }

is to abort without providing a message when the test fail. The
following macro could help

#if defined(BOOST_DISABLE_ASSERTS) || defined(NDEBUG)
# define BOOST_RETURN_IF(Test, Value) return (Val)
#else
# define BOOST_RETURN_IF(Test, Value) \
     if (Test) return (Val); \
     else abort();
#endif

         constexpr const_reference operator[](size_type i)
         {
             return BOOST_RETURN_IF( i < N, elems[i]);
         }

It would be reasonable to raise an issue for c++14. I would expect that
the compiler could be able to manage with assert in a different way when
evaluated at compile time.

Best,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk