Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how does __glibcxx_function_requires and __glibcxx_requires_valid_range macros work?

template<typename _InputIterator, typename _Tp, typename _BinaryOperation>
inline _Tp
accumulate(_InputIterator __first, _InputIterator __last, _Tp __init, _BinaryOperation __binary_op)
{
    // concept requirements
    __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
    __glibcxx_requires_valid_range(__first, __last);

    for (; __first != __last; ++__first)
        __init = __binary_op(__init, *__first);
    return __init;
}

I looked at definition of accumulate function in stl library. Here I found two macros __glibcxx_function_requires and __glibcxx_requires_valid_range, which are defined like this:

#define __glibcxx_function_requires(...)
# define __glibcxx_requires_valid_range(_First,_Last)

Please can you explain me, how they work and what they are doing ?

like image 703
Yoh0xFF Avatar asked Apr 10 '13 20:04

Yoh0xFF


1 Answers

When _GLIBCXX_CONCEPT_CHECKS is defined, so is this.

#define __glibcxx_function_requires(...)                                 \
         __gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >();

So your posted code:

__glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)

Resolves to this:

__gnu_cxx::__function_requires< _InputIteratorConcept<_InputIterator> >();

Which inlines to:

void (_InputIteratorConcept<_InputIterator>::*__x)() _IsUnused = &_InputIteratorConcept<_InputIterator>::__constraints;

This forces an instantiation of _InputIteratorConcept<_InputIterator>::__constraints, which uses typedefs to break compilation when _InputIterator doesn't resemble an iterator.

__glibcxx_requires_valid_range uses a similar technique to call one of several functions, depending on the iterator type. When appropriate (and fast enough), it will assert that __last comes after __first

like image 129
Drew Dormann Avatar answered Oct 26 '22 03:10

Drew Dormann