Add circulator concepts and a (not useful) test-case.

This commit is contained in:
Philipp Möller 2012-11-16 22:05:10 +01:00
parent 3d253a0edd
commit e2502e5b16
2 changed files with 127 additions and 0 deletions

View File

@ -0,0 +1,95 @@
#ifndef CGAL_CIRCULATOR_CONCEPTS_H
#define CGAL_CIRCULATOR_CONCEPTS_H
#include <boost/concept/assert.hpp>
#include <boost/concept_check.hpp>
#include <boost/concept/detail/concept_def.hpp>
#include <iterator>
#include <CGAL/circulator_bases.h>
namespace CGAL { namespace Concepts {
// N.B.: there is no such concept as Circulator as it is immaterial
template <typename C>
struct ForwardCirculator
: boost::Assignable<C>, boost::DefaultConstructible<C>
, boost::CopyConstructible<C>
{
// for some odd reason circulators have no associated traits
typedef typename C::value_type value_type;
typedef typename C::reference reference;
typedef typename C::pointer pointer;
typedef typename C::difference_type difference_type;
// odd name but useful for compatibility
typedef typename C::iterator_category iterator_category;
// this requirement ought to be a mistake because it breaks
// compatibility with iterators
// typedef typename C::size_type size_type;
BOOST_CONCEPT_USAGE(ForwardCirculator)
{
BOOST_CONCEPT_ASSERT((boost::SignedInteger<difference_type>));
BOOST_CONCEPT_ASSERT((boost::Convertible<iterator_category, CGAL::Forward_circulator_tag>));
boost::require_boolean_expr(a == NULL);
boost::require_boolean_expr(a != NULL);
++a;
a++;
(void)*a; // suppress unused warning, don't check the return type
// to allow for proxies
}
private:
C a;
};
template<typename C>
struct BidirectionalCirculator
: ForwardCirculator<C>
{
BOOST_CONCEPT_USAGE(BidirectionalCirculator)
{
BOOST_CONCEPT_ASSERT((boost::Convertible<typename C::iterator_category, CGAL::Bidirectional_circulator_tag>));
--a;
a--;
}
private:
C a;
};
template<typename C>
struct RandomAccessCirculator
: BidirectionalCirculator<C>
{
BOOST_CONCEPT_USAGE(RandomAccessCirculator)
{
BOOST_CONCEPT_ASSERT((boost::Convertible<typename C::iterator_category, CGAL::Random_access_circulator_tag>));
c += n; // addition
c = c + n; c = n + c;
c -= n; // subtraction
c = c - n;
n = c - b; // difference
(void)c[n]; // operator[]
c.min_circulator(); // minimum
}
private:
C c, b;
C i;
typename C::difference_type n;
};
} // Concept
} // CGAL
#include <boost/concept/detail/concept_undef.hpp>
#endif /* CGAL_CIRCULATOR_CONCEPTS_H */

View File

@ -0,0 +1,32 @@
#include <vector>
#include <list>
#include <boost/concept/assert.hpp>
#include <CGAL/circulator.h>
#include <CGAL/Circulator/Circulator_concepts.h>
int main()
{
// test Circulator_from_container
typedef CGAL::Circulator_from_container< std::vector<int> > Circulator_from_vec;
typedef CGAL::Circulator_from_container< std::list<int> > Circulator_from_list;
// neither of the container adaptors passes the checks for tag
// convertibility
// BOOST_CONCEPT_ASSERT((CGAL::Concepts::RandomAccessCirculator<Circulator_from_vec>));
// BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator<Circulator_from_list>));
typedef CGAL::Circulator_from_iterator<int*> Circulator_from_intp;
typedef CGAL::Circulator_from_iterator<std::vector<int>::iterator> Circulator_from_veci;
typedef CGAL::Circulator_from_iterator<std::list<int>::iterator> Circulator_from_listi;
// same as above
// BOOST_CONCEPT_ASSERT((CGAL::Concepts::RandomAccessCirculator<Circulator_from_intp>));
// BOOST_CONCEPT_ASSERT((CGAL::Concepts::RandomAccessCirculator<Circulator_from_veci>));
// BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator<Circulator_from_listi>));
return 0;
}