Boost - Concept - Check C++ Source Code
Boost - Concept - Check C++ Source Code
#define _BOOST_CONCEPT_CHECK_H 1
namespace __gnu_cxx
{
// When the C-C code is in use, we would like this function to do as little
// as possible at runtime, use as few resources as possible, and hopefully
// be elided out of existence... hmmm.
template <class _Concept>
inline void __function_requires()
{
void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
}
_concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
//===========================================================================
// Basic Concepts
// The SGI STL version of Assignable requires copy constructor and operator=
template <class _Tp>
struct _SGIAssignableConcept
{
void __constraints() {
_Tp __b _IsUnused(__a);
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
_Tp __c _IsUnused(__b);
__a = __b; // const required for argument to assignment
}
_Tp __a;
};
// The C++ standard requirements for many concepts talk about return
// types that must be "convertible to bool". The problem with this
// requirement is that it leaves the door open for evil proxies that
// define things like operator|| with strange return types. Two
// possible solutions are:
// 1) require the return type to be exactly bool
// 2) stay with convertible to bool, and also
// specify stuff about all the logical operators.
// For now we just test for convertible to bool.
template <class _Tp>
void __aux_require_boolean_expr(const _Tp& __t) {
bool __x _IsUnused = __t;
}
// FIXME
template <class _Tp>
struct _EqualityComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a == __b);
}
_Tp __a, __b;
};
#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
template <class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
bool __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
template <class _Ret, class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
_Ret __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
//===========================================================================
// Function Object Concepts
// use this when functor is used inside a container class like std::set
template <class _Func, class _First, class _Second>
struct _Const_BinaryPredicateConcept {
void __constraints() {
__const_constraints(__f);
}
void __const_constraints(const _Func& __fun) {
__function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
// operator() must be a const member function
__aux_require_boolean_expr(__fun(__a, __b));
}
_Func __f;
_First __a;
_Second __b;
};
//===========================================================================
// Iterator Concepts
//===========================================================================
// Container Concepts
void __constraints() {
__function_requires< _InputIteratorConcept<_Const_iterator> >();
__function_requires< _AssignableConcept<_Container> >();
const _Container __c;
__i = __c.begin();
__i = __c.end();
__n = __c.size();
__n = __c.max_size();
__b = __c.empty();
}
bool __b;
_Const_iterator __i;
_Size_type __n;
};
void __constraints() {
__function_requires< _ContainerConcept<_Container> >();
__function_requires< _AssignableConcept<_Value_type> >();
__function_requires< _InputIteratorConcept<_Iterator> >();
__i = __c.begin();
__i = __c.end();
__c.swap(__c2);
}
_Iterator __i;
_Container __c, __c2;
};
void __constraints() {
__function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
__function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
__function_requires<
_BidirectionalIteratorConcept<_Const_reverse_iterator> >();
void __constraints() {
__function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
__function_requires<
_Mutable_ForwardContainerConcept<_ReversibleContainer> >();
__function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
void __constraints() {
__function_requires<
_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
__function_requires<
_RandomAccessIteratorConcept<_Const_reverse_iterator> >();
void __constraints() {
__function_requires<
_RandomAccessContainerConcept<_RandomAccessContainer> >();
__function_requires<
_Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
void __constraints() {
// Matt Austern's book puts DefaultConstructible here, the C++
// standard places it in Container
// function_requires< DefaultConstructible<Sequence> >();
__function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
__function_requires< _DefaultConstructibleConcept<_Sequence> >();
_Sequence
__c _IsUnused(__n),
__c2 _IsUnused(__n, __t),
__c3 _IsUnused(__first, __last);
__c.insert(__p, __t);
__c.insert(__p, __n, __t);
__c.insert(__p, __first, __last);
__c.erase(__p);
__c.erase(__p, __q);
__c.push_front(__t);
__c.pop_front();
}
_FrontInsertionSequence __c;
typename _FrontInsertionSequence::value_type __t;
};
void __constraints() {
__function_requires< _SequenceConcept<_BackInsertionSequence> >();
__c.push_back(__t);
__c.pop_back();
_Reference __r _IsUnused = __c.back();
}
void __const_constraints(const _BackInsertionSequence& __c) {
_Const_reference __r _IsUnused = __c.back();
};
_BackInsertionSequence __c;
typename _BackInsertionSequence::value_type __t;
};
__i = __c.find(__k);
__r = __c.equal_range(__k);
__c.erase(__k);
__c.erase(__i);
__c.erase(__r.first, __r.second);
__const_constraints(__c);
}
void __const_constraints(const _AssociativeContainer& __c) {
__ci = __c.find(__k);
__n = __c.count(__k);
__cr = __c.equal_range(__k);
}
typedef typename _AssociativeContainer::iterator _Iterator;
typedef typename _AssociativeContainer::const_iterator _Const_iterator;
_AssociativeContainer __c;
_Iterator __i;
std::pair<_Iterator,_Iterator> __r;
_Const_iterator __ci;
std::pair<_Const_iterator,_Const_iterator> __cr;
typename _AssociativeContainer::key_type __k;
typename _AssociativeContainer::size_type __n;
};
__pos_flag = __c.insert(__t);
__c.insert(__first, __last);
}
std::pair<typename _UniqueAssociativeContainer::iterator, bool> __pos_flag;
typename _UniqueAssociativeContainer::value_type __t;
typename _UniqueAssociativeContainer::value_type *__first, *__last;
};
__pos = __c.insert(__t);
__c.insert(__first, __last);
}
typename _MultipleAssociativeContainer::iterator __pos;
typename _MultipleAssociativeContainer::value_type __t;
typename _MultipleAssociativeContainer::value_type *__first, *__last;
};
_SortedAssociativeContainer
__c _IsUnused(__kc),
__c2 _IsUnused(__first, __last),
__c3 _IsUnused(__first, __last, __kc);
__p = __c.upper_bound(__k);
__p = __c.lower_bound(__k);
__r = __c.equal_range(__k);
__c.insert(__p, __t);
}
void __const_constraints(const _SortedAssociativeContainer& __c) {
__kc = __c.key_comp();
__vc = __c.value_comp();
__cp = __c.upper_bound(__k);
__cp = __c.lower_bound(__k);
__cr = __c.equal_range(__k);
}
typename _SortedAssociativeContainer::key_compare __kc;
typename _SortedAssociativeContainer::value_compare __vc;
typename _SortedAssociativeContainer::value_type __t;
typename _SortedAssociativeContainer::key_type __k;
typedef typename _SortedAssociativeContainer::iterator _Iterator;
typedef typename _SortedAssociativeContainer::const_iterator
_Const_iterator;
_Iterator __p;
_Const_iterator __cp;
std::pair<_Iterator,_Iterator> __r;
std::pair<_Const_iterator,_Const_iterator> __cr;
typename _SortedAssociativeContainer::value_type *__first, *__last;
};
// HashedAssociativeContainer
} // namespace __gnu_cxx
#undef _IsUnused
#endif // _GLIBCXX_BOOST_CONCEPT_CHECK