use rangelib to simplify things, probably should remove extra gunk from rangelib at some point

This commit is contained in:
Daniel Russel 2009-04-08 22:02:37 +00:00
parent 9409f1f68c
commit 9f2f9be17a
23 changed files with 5656 additions and 61 deletions

19
.gitattributes vendored
View File

@ -2633,6 +2633,25 @@ PDB/include/CGAL/PDB/internal/align_points.h -text
PDB/include/CGAL/PDB/internal/dummies.h -text
PDB/include/CGAL/PDB/internal/foreach.h -text
PDB/include/CGAL/PDB/internal/pdb_utils.h -text
PDB/include/CGAL/PDB/internal/rangelib/algo.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/algo_old.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/break.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/filter.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/generate.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/indirect.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/multi.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/multi_byeach.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/multi_byrange.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/priv/defs.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/priv/rng_fun.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/priv/traits.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/range.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/resort.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/reverse.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/slice.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/slice_byeach.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/slice_byrange.hpp -text
PDB/include/CGAL/PDB/internal/rangelib/transform.hpp -text
PDB/include/CGAL/PDB/internal/tnt/jama_cholesky.h -text
PDB/include/CGAL/PDB/internal/tnt/jama_eig.h -text
PDB/include/CGAL/PDB/internal/tnt/jama_lu.h -text

View File

@ -6,6 +6,7 @@
#include <CGAL/PDB/internal/tnt/tnt_array2d.h>
#include <CGAL/PDB/internal/tnt/jama_svd.h>
#include <CGAL/PDB/Matrix.h>
#include <CGAL/PDB/range.h>
namespace CGAL { namespace PDB {
@ -43,9 +44,8 @@ inline std::ostream &operator<<(std::ostream &o, DpP p){
*/
template <class RP, class RQ>
Transform transform_taking_first_to_second(RP rp, RQ rq){
CGAL_assertion(std::distance(rp.begin(), rp.end())
== std::distance(rq.begin(), rq.end()));
CGAL_precondition(!rp.empty());
CGAL_precondition(CGAL::PDB::distance(rp)== CGAL::PDB::distance(rq));
CGAL_precondition(CGAL::PDB::distance(rp) != 0);
// compute the centroid of the points and transform
// pointsets so that their centroids coinside

View File

@ -35,8 +35,8 @@ double cRMS(const RangeA& ra, const RangeB& rb,
const Transform &tr=Transform(1,0,0,0,
0,1,0,0,
0,0,1,0)) {
CGAL_precondition(std::distance(ra.begin(), ra.end())
== std::distance(rb.begin(), rb.end());
CGAL_precondition(CGAL::PDB::distance(ra) == CGAL::PDB::distance(rb));
double ret=0;
int num=0;
{

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,886 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_ALGO_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_ALGO_HPP_INCLUDED
#include <algorithm>
#include <iterator>
#include <iosfwd>
#include <boost/config.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
/*
Notes:
1. For the purpose of algorithms, EVERY container IS a range.
2. All predicates are passed by value, since VC6 does not hadle 'const Pred&' well,
when they are functions.
3. At this time (14th Nov 2003), all STL algorithms are implemented, except for:
- partial_sort_copy
- mismatch
// FIXME - implement <numeric> algorithms as well
*/
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
template< class value_type, class char_type, class traits_type>
irange< ::std::istream_iterator< value_type, char_type, traits_type> > istream_range( ::std::basic_istream<char_type,traits_type> & s) {
typedef ::std::istream_iterator< value_type, char_type, traits_type> it_type;
typedef irange< it_type > range_type;
return range_type( it_type(s), it_type() );
}
// helper - for passing an iterator instead of a range as a second parameter,
// to an algorithm that needs two ranges (example: mismatch)
//
// You can have
// - rng::mismatch( rng1, rng2); // passing two ranges
// - rng::mismatch( rng, i_(iterator) ); // passing the second param as an iterator
// - rng::mismatch( rng, i_param(iterator) ); // same as above, but more descriptive
template< class it>
struct i_param_t {
typedef it iterator;
i_param_t( iterator first) : m_first(first) {}
iterator begin() const { return m_first;}
// provided for copy_backward, which if a range is the second param, will copy starting from its end
iterator end() const { return m_first;}
private:
iterator m_first;
};
// shorter form: 'i_'
template<class it> inline i_param_t<it> i_( it val) { return i_param_t<it>(val); }
// longer and more descriptable/readable form 'i_param'
template<class it> inline i_param_t<it> i_param( it val) { return i_param_t<it>(val); }
namespace rng {
template< class r1, class r2>
struct mismatch_return_finder {
typedef typename range_finder<r1>::range_type r1_range_type;
typedef typename r1_range_type::iterator it1;
typedef typename r2::iterator it2;
typedef ::std::pair<it1, it2> return_type;
};
/*
Algorithms that DO NOT return a range.
*/
//template<class in_it> typename iterator_traits<in_it>::difference_type
//distance(in_it first, in_it last);
// FIXME - return difference_type
CGAL_PDB_BOOST_RTL_RNG_ALGO10( distance, int)
//template <class in_it, class Distance>
//void advance(in_it& i, Distance n);
template< class iterator, class Distance> inline
iterator advanced( iterator i, Distance n) {
::std::advance(i, n);
return i;
}
//template<class in_it, class Function>
//Function for_each(in_it first, in_it last, Function f);
CGAL_PDB_BOOST_RTL_RNG_ALGO11( for_each, function, function, function)
// template<class in_it, class T> typename iterator_traits<in_it>::difference_type
// count(in_it first, in_it last, const T& value);
// FIXME - in the future, use difference_type
CGAL_PDB_BOOST_RTL_RNG_ALGO11( count, int, T, const T&)
// template<class in_it, class Predicate> typename iterator_traits<in_it>::difference_type
// count_if(in_it first, in_it last, Predicate pred);
// FIXME - in the future, use difference_type
CGAL_PDB_BOOST_RTL_RNG_ALGO11( count_if, int, T, T)
//
// template<class in_it1, class in_it2> pair<in_it1, in_it2>
// mismatch(in_it1 first1, in_it1 last1, in_it2 first2);
template< class r1, class r2>
struct mismatch_return_finder {
typedef typename range_finder<r1>::range_type r1_range_type;
typedef typename r1_range_type::iterator it1;
// FIXME - if r2 is a const container, use const_iterator!!!
typedef typename r2::iterator it2;
typedef ::std::pair<it1, it2> return_type;
};
//FIXME - fails under VC6
//CGAL_PDB_BOOST_RTL_RNG_ALGO20( mismatch, (BOOST_DEDUCED_TYPENAME mismatch_return_finder<r1,r2>::return_type))
mismatch
//
// template<class in_it1, class in_it2, class BinaryPredicate> pair<in_it1, in_it2>
// mismatch(in_it1 first1, in_it1 last1, in_it2 first2, BinaryPredicate pred);
//FIXME - fails under VC6
//CGAL_PDB_BOOST_RTL_RNG_ALGO21( mismatch, (BOOST_DEDUCED_TYPENAME mismatch_return_finder<r1,r2>::return_type), pred, pred)
//
// template<class in_it1, class in_it2> bool
// equal(in_it1 first1, in_it1 last1, in_it2 first2);
CGAL_PDB_BOOST_RTL_RNG_ALGO20( equal, bool)
//
// template<class in_it1, class in_it2, class BinaryPredicate> bool
// equal(in_it1 first1, in_it1 last1, in_it2 first2, BinaryPredicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO21( equal, bool, pred, pred)
//
// template<class in_it, class out_it> out_it
// copy(in_it first, in_it last, out_it result);
CGAL_PDB_BOOST_RTL_RNG_ALGO11( copy, out_it, out_it, out_it)
//
// template<class bid_it1, class bid_it2> bid_it2
// copy_backward(bid_it1 first, bid_it1 last, bid_it2 result);
// FIXME - here, we could actually return a range
CGAL_PDB_BOOST_RTL_RNG_ALGO20( copy_backward, BOOST_DEDUCED_TYPENAME r2::iterator)
//
// template<class fwd_it1, class fwd_it2> fwd_it2
// swap_ranges(fwd_it1 first1, fwd_it1 last1, fwd_it2 first2);
// FIXME - here, we could actually return a range
CGAL_PDB_BOOST_RTL_RNG_ALGO20( swap_ranges, BOOST_DEDUCED_TYPENAME r2::iterator)
//
// template<class fwd_it1, class fwd_it2>
// void iter_swap(fwd_it1 a, fwd_it2 b);
//CGAL_PDB_BOOST_RTL_RNG_ALGO20_void( iter_swap)
//
// template<class in_it, class out_it, class UnaryOperation> out_it
// transform(in_it first, in_it last, out_it result, UnaryOperation op);
CGAL_PDB_BOOST_RTL_RNG_ALGO12( transform, out_it, out_it, out_it, op, op)
//
// template<class in_it1, class in_it2, class out_it, class BinaryOperation> out_it
// transform(in_it1 first1, in_it1 last1, in_it2 first2, out_it result, BinaryOperation binary_op);
CGAL_PDB_BOOST_RTL_RNG_ALGO22( transform, out_it, out_it, out_it, op, op)
//
// template<class fwd_it, class T> void
// replace(fwd_it first, fwd_it last, const T& old_value, const T& new_value);
CGAL_PDB_BOOST_RTL_RNG_ALGO12_void( replace, T, const T&, T_same, const T_same&)
//
// template<class fwd_it, class Predicate, class T> void
// replace_if(fwd_it first, fwd_it last, Predicate pred, const T& new_value);
CGAL_PDB_BOOST_RTL_RNG_ALGO12_void( replace_if, pred, pred, T, const T&)
//
// template<class in_it, class out_it, class T> out_it
// replace_copy(in_it first, in_it last, out_it result, const T& old_value, const T& new_value);
CGAL_PDB_BOOST_RTL_RNG_ALGO13( replace_copy, out_it, out_it, out_it, T, const T&, T_same, const T_same&)
//
// template<class Iterator, class out_it, class Predicate, class T> out_it
// replace_copy_if(Iterator first, Iterator last, out_it result, Predicate pred, const T& new_value);
CGAL_PDB_BOOST_RTL_RNG_ALGO13( replace_copy_if, out_it, out_it, out_it, pred, pred, T, const T&)
//
// template<class fwd_it, class T> void
// fill(fwd_it first, fwd_it last, const T& value);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( fill, T, const T&)
//
// template<class out_it, class Size, class T> void
// fill_n(out_it first, Size n, const T& value);
//useless - CGAL_PDB_BOOST_RTL_RNG_ALGO12_void( fill_n, Size, Size, T, const T&)
//
// template<class fwd_it, class Generator> void
// generate(fwd_it first, fwd_it last, Generator gen);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( generate, generator, generator)
//
// template<class out_it, class Size, class Generator> void
// generate_n(out_it first, Size n, Generator gen);
// useless - CGAL_PDB_BOOST_RTL_RNG_ALGO12_void( generate_n, Size, Size, generator, generator)
//
// template<class in_it, class out_it> out_it
// unique_copy(in_it first, in_it last, out_it result);
CGAL_PDB_BOOST_RTL_RNG_ALGO11( unique_copy, out_it, out_it, out_it)
//
// template<class in_it, class out_it, class BinaryPredicate> out_it
// unique_copy(in_it first, in_it last, out_it result, BinaryPredicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO12( unique_copy, out_it, out_it, out_it, pred, pred)
//
// template<class bid_it> void
// reverse(bid_it first, bid_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_void( reverse)
//
// template<class bid_it, class out_it> out_it
// reverse_copy(bid_it first, bid_it last, out_it result);
CGAL_PDB_BOOST_RTL_RNG_ALGO11( reverse_copy, out_it, out_it, out_it)
//
// template<class fwd_it> void
// rotate(fwd_it first, fwd_it middle, fwd_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( rotate, fwd_it, fwd_it)
//
// template<class fwd_it, class out_it> out_it
// rotate_copy(fwd_it first, fwd_it middle, fwd_it last, out_it result);
CGAL_PDB_BOOST_RTL_RNG_ALGO12( rotate_coy, out_it, fwd_it, fwd_it, out_it, out_it)
//
// template<class rand_it> void
// random_shuffle(rand_it first, rand_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_void( random_shuffle)
//
// template<class rand_it, class RandomNumberGenerator> void
// random_shuffle(rand_it first, rand_it last, RandomNumberGenerator& rand);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( random_shuffle, generator, generator&)
//
// template<class rand_it> void
// sort(rand_it first, rand_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_void( sort)
//
// template<class rand_it, class Compare>
// void sort(rand_it first, rand_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( sort, pred, pred)
//
// template<class rand_it> void
// stable_sort(rand_it first, rand_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_void( stable_sort)
//
// template<class rand_it, class Compare> void
// stable_sort(rand_it first, rand_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( stable_sort, pred, pred)
//
// template<class rand_it> void
// partial_sort(rand_it first, rand_it middle, rand_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( partial_sort, rand_it, rand_it)
//
// template<class rand_it, class Compare> void
// partial_sort(rand_it first, rand_it middle, rand_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO12_void( partial_sort, rand_it, rand_it, pred, pred)
//
// template<class rand_it> void
// nth_element(rand_it first, rand_it nth, rand_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( nth_element, rand_it, rand_it)
//
// template<class rand_it, class Compare> void
// nth_element(rand_it first, rand_it nth, rand_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO12_void( nth_element, rand_it, rand_it, pred, pred)
//
// template<class fwd_it, class T> bool
// binary_search(fwd_it first, fwd_it last, const T& value);
CGAL_PDB_BOOST_RTL_RNG_ALGO11( binary_search, bool, T, const T&)
//
// template<class fwd_it, class T, class Compare> bool
// binary_search(fwd_it first, fwd_it last, const T& value, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO12( binary_search, bool, T, const T&, pred, pred)
//
// template<class in_it1, class in_it2, class out_it> out_it
// merge(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_2param( merge, out_it, out_it, out_it)
//
// template<class in_it1, class in_it2, class out_it, class Compare> out_it
// merge(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO22_2param( merge, out_it, out_it, out_it, pred, pred)
//
// template<class bid_it> void
// inplace_merge(bid_it first, bid_it middle, bid_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( inplace_merge, bid_it, bid_it)
//
// template<class bid_it, class Compare> void
// inplace_merge(bid_it first, bid_it middle, bid_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO12_void( inplace_merge, bid_it, bid_it, pred, pred)
//
// template<class in_it1, class in_it2> bool
// includes(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2);
CGAL_PDB_BOOST_RTL_RNG_ALGO20_2param( includes, bool)
//
// template<class in_it1, class in_it2, class Compare> bool
// includes(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_2param( includes, bool, comp, comp)
//
// template<class in_it1, class in_it2, class out_it> out_it
// set_union(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_2param( set_union, out_it, out_it, out_it)
//
// template<class in_it1, class in_it2, class out_it, class Compare>
// out_it set_union(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO22_2param( set_union, out_it, out_it, out_it, pred, pred)
//
// template<class in_it1, class in_it2, class out_it> out_it
// set_intersection(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_2param( set_intersection, out_it, out_it, out_it)
//
// template<class in_it1, class in_it2, class out_it, class Compare> out_it
// set_intersection(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO22_2param( set_intersection, out_it, out_it, out_it, pred, pred)
//
// template<class in_it1, class in_it2, class out_it> out_it
// set_difference(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_2param( set_difference, out_it, out_it, out_it)
//
// template<class in_it1, class in_it2, class out_it, class Compare> out_it
// set_difference(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO22_2param( set_difference, out_it, out_it, out_it, pred, pred)
//
// template<class in_it1, class in_it2, class out_it> out_it
// set_symmetric_difference(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_2param( set_symmetric_difference, out_it, out_it, out_it)
//
// template<class in_it1, class in_it2, class out_it, class Compare> out_it
// set_symmetric_difference(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, out_it result, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO22_2param( set_symmetric_difference, out_it, out_it, out_it, pred, pred)
//
//
// template<class rand_it> void
// push_heap(rand_it first, rand_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_void( push_heap)
//
// template<class rand_it, class Compare> void
// push_heap(rand_it first, rand_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( push_heap, pred, pred)
//
// template<class rand_it> void
// pop_heap(rand_it first, rand_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_void( pop_heap)
//
// template<class rand_it, class Compare> void
// pop_heap(rand_it first, rand_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( pop_heap, pred, pred)
//
// template<class rand_it> void
// make_heap(rand_it first, rand_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_void( make_heap)
//
// template<class rand_it, class Compare> void
// make_heap(rand_it first, rand_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( make_heap, pred, pred)
//
// template<class rand_it> void
// sort_heap(rand_it first, rand_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_void( sort_heap)
//
// template<class rand_it, class Compare> void
// sort_heap(rand_it first, rand_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_void( sort_heap, pred, pred)
//
// template<class in_it1, class in_it2> bool
// lexicographical_compare(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2);
CGAL_PDB_BOOST_RTL_RNG_ALGO20_2param( lexicographical_compare, bool)
//
// template<class in_it1, class in_it2, class Compare> bool
// lexicographical_compare(in_it1 first1, in_it1 last1, in_it2 first2, in_it2 last2, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_2param( lexicographical_compare, bool, pred, pred)
//
// template<class bid_it> bool
// next_permutation(bid_it first, bid_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10( next_permutation, bool)
//
// template<class bid_it, class Compare> bool
// next_permutation(bid_it first, bid_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11( next_permutation, bool, pred, pred)
//
// template<class bid_it> bool
// prev_permutation(bid_it first, bid_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10( prev_permutation, bool)
//
// template<class bid_it, class Compare> bool
// prev_permutation(bid_it first, bid_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11( prev_permutation, bool, pred, pred)
// template<class in_it, class out_it, class T> out_it
// remove_copy(in_it first, in_it last, out_it result, const T& value);
CGAL_PDB_BOOST_RTL_RNG_ALGO12( remove_copy, out_it, out_it, out_it, T, const T&)
//
// template<class in_it, class out_it, class Predicate> out_it
// remove_copy_if(in_it first, in_it last, out_it result, Predicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO12( remove_copy_if, out_it, out_it, out_it, pred, pred)
////////////////////////////////////////////////////////////////////////////
// from <numerics>
// template <class in_it, class T> T
// accumulate(in_it first, in_it last, T init);
CGAL_PDB_BOOST_RTL_RNG_ALGO11( accumulate, T, T, T)
// template <class in_it, class T, class Func> T
// accumulate(in_it first, in_it last, T init, Func binary_op);
CGAL_PDB_BOOST_RTL_RNG_ALGO12( accumulate, T, T, T, Func, Func)
// template <class in_it1, class in_it2, class T> T
// inner_product(in_it1 first1, in_it1 last1, in_it2 first2, T init);
// template <class in_it1, class in_it2, class T, class Func1, class Func2> T
// inner_product(in_it1 first1, in_it1 last1, in_it2 first2, T init, Func1 binary_op1, Func2 binary_op2);
// template <class in_it, class out_it> out_it
// partial_sum(in_it first, in_it last, out_it result);
// template <class in_it, class out_it, class Func> out_it
// partial_sum(in_it first, in_it last, out_it result, Func binary_op);
// template <class in_it, class out_it> out_it
// adjacent_difference(in_it first, in_it last, out_it result);
// template <class in_it, class out_it, class Func> out_it
// adjacent_difference(in_it first, in_it last, out_it result, Func binary_op);
//
//
//
//
// * These functions returns a range
/*
Right now, we always return a range, from the element "found",
up to the end of the original range.
This might not necessary be what you want.
Therefore, FIXME (to do).
Allow for algorithm of this type:
find_if<what_to_return>(range);
What to return is any of:
1. return the iterator itself ("r_it")
2. (default - as is now) return the range from the
found iterator up to the end ("r_to_end")
3. return the range starting from begin, up to the found iterator ("r_from_beg")
Note: see end of file.
*/
// template<class in_it, class T> in_it
// find(in_it first, in_it last, const T& value);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( find, T, const T&)
//
// template<class in_it, class Predicate> in_it
// find_if(in_it first, in_it last, Predicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( find_if, pred, pred)
//
// template<class fwd_it1, class fwd_it2> fwd_it1
// find_end(fwd_it1 first1, fwd_it1 last1, fwd_it2 first2, fwd_it2 last2);
CGAL_PDB_BOOST_RTL_RNG_ALGO20_EXT( find_end)
//
// template<class fwd_it1, class fwd_it2, class BinaryPredicate> fwd_it1
// find_end(fwd_it1 first1, fwd_it1 last1, fwd_it2 first2, fwd_it2 last2, BinaryPredicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_EXT( find_end, pred, pred)
//
// template<class fwd_it1, class fwd_it2> fwd_it1
// find_first_of(fwd_it1 first1, fwd_it1 last1, fwd_it2 first2, fwd_it2 last2);
CGAL_PDB_BOOST_RTL_RNG_ALGO20_EXT( find_first_of)
//
// template<class fwd_it1, class fwd_it2, class BinaryPredicate> fwd_it1
// find_first_of(fwd_it1 first1, fwd_it1 last1, fwd_it2 first2, fwd_it2 last2, BinaryPredicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_EXT( find_first_of, pred, pred)
//
// template<class fwd_it> fwd_it
// adjacent_find(fwd_it first, fwd_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_EXT( adjacent_find)
// template<class fwd_it, class BinaryPredicate> fwd_it
// adjacent_find(fwd_it first, fwd_it last, BinaryPredicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( adjacent_find, pred, pred)
//
//
// template<class fwd_it1, class fwd_it2> fwd_it1
// search(fwd_it1 first1, fwd_it1 last1, fwd_it2 first2, fwd_it2 last2);
CGAL_PDB_BOOST_RTL_RNG_ALGO20_EXT( search)
//
// template<class fwd_it1, class fwd_it2, class BinaryPredicate> fwd_it1
// search(fwd_it1 first1, fwd_it1 last1, fwd_it2 first2, fwd_it2 last2, BinaryPredicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO21_EXT( search, pred, pred)
//
// template<class fwd_it, class Size, class T> fwd_it
// search_n(fwd_it first, fwd_it last, Size count, const T& value);
CGAL_PDB_BOOST_RTL_RNG_ALGO12_EXT( search_n, Size, Size, T, const T&)
//
// template<class fwd_it, class Size, class T, class BinaryPredicate> fwd_it1
// search_n(fwd_it first, fwd_it last, Size count, const T& value, BinaryPredicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO13_EXT( search_n, Size, Size, T, const T&, pred, pred)
//
// ***** return the range of elements to be removed;
// use them in correlation with r_erase.
//
// template<class fwd_it, class T> fwd_it
// remove(fwd_it first, fwd_it last, const T& value);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( remove, T, const T&)
//
// template<class fwd_it, class Predicate> fwd_it
// remove_if(fwd_it first, fwd_it last, Predicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( remove_if, pred, pred)
//
// template<class fwd_it> fwd_it
// unique(fwd_it first, fwd_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_EXT( unique)
//
// template<class fwd_it, class BinaryPredicate> fwd_it
// unique(fwd_it first, fwd_it last, BinaryPredicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( unique, pred, pred)
//
//
// // return the range that satisfies the predicate
// template<class bid_it, class Predicate> bid_it
// partition(bid_it first, bid_it last, Predicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( partition, pred, pred)
//
// template<class bid_it, class Predicate> bid_it
// stable_partition(bid_it first, bid_it last, Predicate pred);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( stable_partition, pred, pred)
//
// template<class in_it, class rand_it> rand_it
// partial_sort_copy(in_it first, in_it last, rand_it result_first, rand_it result_last);
// FIXME - watch out what we return!!!
//
// template<class in_it, class rand_it, class Compare> rand_it
// partial_sort_copy(in_it first, in_it last, rand_it result_first, rand_it result_last, Compare comp);
// FIXME - watch out what we return!!!
//
// template<class fwd_it, class T> fwd_it
// lower_bound(fwd_it first, fwd_it last, const T& value);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( lower_bound, T, const T&)
//
// template<class fwd_it, class T, class Compare> fwd_it
// lower_bound(fwd_it first, fwd_it last, const T& value, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO12_EXT( lower_bound, T, const T&, pred, pred)
//
// template<class fwd_it, class T> fwd_it
// upper_bound(fwd_it first, fwd_it last, const T& value);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( upper_bound, T, const T&)
//
// template<class fwd_it, class T, class Compare> fwd_it
// upper_bound(fwd_it first, fwd_it last, const T& value, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO12_EXT( upper_bound, T, const T&, pred, pred)
//
// template<class fwd_it, class T> pair<fwd_it, fwd_it>
// equal_range(fwd_it first, fwd_it last, const T& value);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT2( equal_range, T, const T&)
//
// template<class fwd_it, class T, class Compare> pair<fwd_it, fwd_it>
// equal_range(fwd_it first, fwd_it last, const T& value, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO12_EXT2( equal_range, T, const T&, pred, pred)
//
// template<class fwd_it> fwd_it
// min_element(fwd_it first, fwd_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_EXT( min_element)
//
// template<class fwd_it, class Compare> fwd_it
// min_element(fwd_it first, fwd_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( min_element, pred, pred)
//
// template<class fwd_it> fwd_it
// max_element(fwd_it first, fwd_it last);
CGAL_PDB_BOOST_RTL_RNG_ALGO10_EXT( max_element)
//
// template<class fwd_it, class Compare> fwd_it
// max_element(fwd_it first, fwd_it last, Compare comp);
CGAL_PDB_BOOST_RTL_RNG_ALGO11_EXT( max_element, pred, pred)
#if 0
I just thought about it, and one could actually say:
r.begin( v.erase(r.begin()) );
So I could add a function called errase_current which would implement this idiom. Does that make sense?
(and it could work for collections as well)
must be done - already written in article listing
FIXME
Hi John and Mathew,
Amid my exam confusion, I came to think on this example.
In normal iterator mode we have
typedef vector<int> vec_t;
vec_t v;
for( vec_t::iterator i = v.begin(); i != v.end(); ++i )
if( something( *i ) )
i = v.erase( i );
notice that we need to recompute the end iterator since erase can invalidate it.
How can we do that with ranges? I guess this would be wrong:
crange<vec_t> r( v );
for( ; r ; ++r ) // not good
if( something(*r) )
r = v.erase( r.begin() );
Do your free-stading erase work:
crange<vec_t> r( v );
for( ; r ; ++r ) /
if( something(*r) )
r = erase( v, r );
? ie, is erase defined as
template< class C >
crange<C> erase( C& c, const crange<C>& r )
{
returrn crange<C>( c.erase( r.begin() ), c.end() );
}
?
btw, I checked the problem with retur values of map/set erase() being void. It turns out that we decided it was a defect
in the standard that the return value is void; hence standard libraries are requiered to change the implementation ASAP, ie, before
C++Ox. I think some libraries already has a non-void return.
br
Thorsten
As was mentioned in the first article, algorithms that return an iterator are indeed a different breed from the rest. You use such an algorithm to:
1. do something to the iterator you get in return, or
2. walk from that iterator to the end or
3. walk from the beginning up to the iterator
In the first two cases, you'll typically be happy with the default range algorithm behavior - you do need to test if the iterator is valid, and if so, use it (or walk to the end). In case you want the algorithm to:
- return only the iterator, and behave like the STL algorithm: use rng::algorithm<iter>() instead of rng::algorithm()
return the [begin, found) range (case 3.): use rng::algorithm<from_beg>() instead of rng::algorithm()
[for searching and find, there might be a couple of other policies: maybe it could also be possible to say
vector<int> v;
find<or_throw>( v, 3 ); // throws an exception on failure
int i = find<or_return_default>( v, is_even() ); // finds first even number or 0 otherwise
]
[Another issue might be to have different overloads for eg. Copy: copy( range, iterator ); copy( range, range);]
This is already solved, just mention it in the docs.
#endif
} // namespace rng
}}}}
#endif
/*
Compiles under VC6 !!!
#include <iostream>
typedef enum range_return_type {
it,
from_beg,
to_end
};
template< class T>
void test( const T& val){
std::cout << "general" << std::endl;
}
template< range_return_type r, class T>
void test( const T& val, range_return_type ignore_vc_bug = r){
std::cout << "specific" << std::endl;
}
struct try_it {};
int main(int argc, char* argv[])
{
test( 1);
test( try_it() );
test<it>( 1 );
test<from_beg>( 2 );
test<it>( try_it() );
test<to_end>( 2 );
}
*/

View File

@ -0,0 +1,163 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_break_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_break_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <boost/iterator.hpp>
// FIXME port everything to work with Thorsten's range_traits lib.
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
template<class iterator_type, class pred>
struct break_iterator : public ::boost::iterator<
::std::input_iterator_tag,
typename ::CGAL::PDB::internal::rangelib::detail::iterator_traits<iterator_type>::value_type> {
typedef typename ::CGAL::PDB::internal::rangelib::detail::iterator_traits<iterator_type>::iterator i_type;
typedef typename ::CGAL::PDB::internal::rangelib::detail::iterator_traits<iterator_type>::value_type v_type;
typedef typename ::CGAL::PDB::internal::rangelib::detail::iterator_traits<iterator_type>::reference r_type;
typedef typename ::CGAL::PDB::internal::rangelib::detail::iterator_traits<iterator_type>::pointer p_type;
typedef break_iterator<iterator_type,pred> self_type;
break_iterator(i_type iter, pred p, bool breaked) : m_iterator(iter), m_p(p), m_breaked(breaked) {
if ( !m_breaked)
check_breaked();
}
self_type& operator++() {
++m_iterator;
check_breaked();
return *this;
}
self_type operator++(int) {
self_type tmp( *this);
++*this;
return tmp;
}
r_type operator*() { return *m_iterator; }
p_type operator->() { return &*m_iterator; }
inline bool operator==( const self_type & other) const {
if ( m_iterator == other.m_iterator) return true;
return m_breaked == other.m_breaked; // see if they reached the end...
}
private:
// see if we've breaked...
void check_breaked() {
if ( m_breaked) return;
m_breaked = !m_p(*m_iterator);
}
private:
pred m_p;
i_type m_iterator;
bool m_breaked;
};
template<class i, class p>
inline bool operator!=( const break_iterator<i,p> & first, const break_iterator<i,p> & second) {
return !(first == second);
}
template< class r, class pred> struct break_iterator_finder {
typedef typename ::CGAL::PDB::internal::rangelib::range_finder<r>::range_type r_type;
typedef typename r_type::iterator i_type;
typedef ::CGAL::PDB::internal::rangelib::detail::break_iterator<i_type, pred> break_type;
};
}
/*
Wraps a range or a container
When a certain functor returns false, it "breaks".
It is equivalent to:
for ( some_range r(...); r; ++r)
if ( some_functor(*r) )
do_something( *r);
else
break; // **********
*/
template< class r, class pred>
struct breaked_range : public irange< typename ::CGAL::PDB::internal::rangelib::detail::break_iterator_finder<r, pred>::break_type > {
typedef irange< typename ::CGAL::PDB::internal::rangelib::detail::break_iterator_finder<r, pred>::break_type > base;
typedef typename ::CGAL::PDB::internal::rangelib::detail::break_iterator_finder<r, pred>::i_type old_iterator;
typedef typename ::CGAL::PDB::internal::rangelib::detail::break_iterator_finder<r, pred>::break_type new_iterator;
breaked_range( old_iterator first, old_iterator last, pred p = pred() )
: base( new_iterator(first,p,false), new_iterator(last,p,true) ) {
}
breaked_range( r & rng, pred p = pred() )
: base( new_iterator( rng.begin(),p,false),
new_iterator( rng.end(),p,true) ) {
}
};
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class r, class pred> inline breaked_range<const r,pred>
breaked( const r & rng, pred p) {
return breaked_range<const r,pred>( rng.begin(), rng.end(), p);
}
#endif
template< class r, class pred> inline breaked_range<r,pred>
breaked( r & rng, pred p) {
return breaked_range<r,pred>( rng.begin(), rng.end(), p);
}
// helper for breaked() - it breaks after n elements.
struct bk_after {
bk_after(int n) : m_n(n), m_idx(0) {}
template<class value_type> bool operator()(const value_type&) {
return m_idx++ < m_n;
}
private:
int m_n, m_idx;
};
typedef bk_after break_after; // longer name, if you wish ;)
}}}}
#endif
/**
FIXME
have predicate for stoppping.
break_at()
- make it simple to specify something like break_after(n) - breaks after n elements
*/

View File

@ -0,0 +1,74 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_FILTER_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_FILTER_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <boost/iterator/filter_iterator.hpp>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
template< class r, class pred>
struct filter_iterator_finder {
typedef typename ::CGAL::PDB::internal::rangelib::range_finder<r>::range_type r_type;
typedef typename r_type::iterator i_type;
typedef ::boost::filter_iterator<pred, i_type> filter_type;
};
}
// filters a range or a container
template< class r, class pred>
struct filtered_range : public irange< typename ::CGAL::PDB::internal::rangelib::detail::filter_iterator_finder<r, pred>::filter_type > {
typedef irange< typename ::CGAL::PDB::internal::rangelib::detail::filter_iterator_finder<r, pred>::filter_type > base;
typedef typename ::CGAL::PDB::internal::rangelib::detail::filter_iterator_finder<r, pred>::i_type old_iterator;
typedef typename ::CGAL::PDB::internal::rangelib::detail::filter_iterator_finder<r, pred>::filter_type new_iterator;
filtered_range( old_iterator first, old_iterator last, pred p = pred() )
: base( new_iterator(p,first,last), new_iterator(p,last,last) ) {
}
filtered_range( r & rng, pred p = pred() )
: base( new_iterator(p,rng.begin(),rng.end()),
new_iterator(p,rng.end(),rng.end() ) ) {
}
};
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class r, class pred> inline filtered_range<const r,pred>
filtered( const r & rng, pred p) {
return filtered_range<const r,pred>( rng.begin(), rng.end(), p);
}
#endif
template< class r, class pred> inline filtered_range<r,pred>
filtered( r & rng, pred p) {
return filtered_range<r,pred>( rng.begin(), rng.end(), p);
}
}}}}
#endif

View File

@ -0,0 +1,180 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_GENERATE_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_GENERATE_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <boost/iterator.hpp>
#include <functional>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
struct end_iterator {};
template< class res>
struct generator_functor {
typedef res (*func)();
typedef res result_type;
generator_functor( func f) : m_f(f) {}
result_type operator() () { return m_f(); }
private:
func m_f;
};
// note: result_type must be Assignable and copy-constructible
//
// the stopper will return false when we should stop
template< class generator, class stopper>
struct generated_iterator : public ::boost::iterator<
::std::input_iterator_tag, typename generator::result_type> {
typedef generated_iterator<generator, stopper> self_type;
typedef typename generator::result_type result_type;
generated_iterator( generator g, stopper s)
: m_g( g), m_s( s), m_more( true),
m_val( m_g() ) {
check_more();
}
generated_iterator( generator g, stopper s, const end_iterator & )
: m_g( g), m_s( s), m_more( false),
// initializing to this, since the result_type is not required to be
// default constructible
m_val( m_g() ) {
}
self_type& operator++() {
m_val = m_g();
check_more();
return *this;
}
self_type operator++(int) {
self_type tmp( *this);
++*this;
return tmp;
}
const result_type& operator*() const { return m_val; }
const result_type* operator->() const { return &m_val; }
bool more() const { return m_more; }
private:
void check_more() {
m_more = m_s( m_val); // see if reached the end
}
private:
generator m_g;
stopper m_s;
bool m_more;
// must be INITIALIZED Last (because it depends on m_g)
result_type m_val;
};
template<class g, class s>
inline bool operator==( const generated_iterator<g,s> & first, const generated_iterator<g,s> & second) {
return first.more() == second.more();
}
template<class g, class s>
inline bool operator!=( const generated_iterator<g,s> & first, const generated_iterator<g,s> & second) {
return first.more() != second.more();
}
}
// represents a range, generated from a functor (generated)
//
// see the ::std::generate/ ::std::generate_n algorithms
template< class generator, class stopper>
struct generated_range : public irange< ::CGAL::PDB::internal::rangelib::detail::generated_iterator<generator,stopper> > {
typedef ::CGAL::PDB::internal::rangelib::detail::generated_iterator<generator,stopper> iterator_type;
typedef irange< iterator_type> base;
generated_range( generator g, stopper s)
: base( iterator_type(g, s),
iterator_type(g, s, ::CGAL::PDB::internal::rangelib::detail::end_iterator()) ) {
}
};
template< class generator, class stopper>
generated_range<generator,stopper> generated( generator g, stopper s) {
return generated_range<generator,stopper>( g,s);
}
template< class res, class stopper>
generated_range< ::CGAL::PDB::internal::rangelib::detail::generator_functor<res>, stopper> generated_f( res (*g)(), stopper s) {
typedef ::CGAL::PDB::internal::rangelib::detail::generator_functor<res> g_type;
return generated_range<g_type,stopper>( g_type(g), s);
}
///////////////////////////////////////////////////////////////////
// Stoppers
// returns the first n elements from the range
struct gen_n {
gen_n( int n) : m_remaining(n) {}
template<class value_type> bool operator() ( const value_type &) {
return m_remaining-- > 0;
}
private:
int m_remaining;
};
// generates up to a given value (EXCLUDING that value)
template< class value_type>
struct gen_upto_t {
gen_upto_t( value_type val) : m_val( val) {}
bool operator()( const value_type & other) const {
return other < m_val;
}
private:
value_type m_val;
};
template< class value_type> inline gen_upto_t<value_type>
gen_upto( value_type val) {
return gen_upto_t<value_type>( val);
}
// generates down to a given value (EXCLUDING that value)
template< class value_type>
struct gen_downto_t {
gen_downto_t( value_type val) : m_val( val) {}
bool operator()( const value_type & other) const {
return m_val < other;
}
private:
value_type m_val;
};
template< class value_type> inline gen_downto_t<value_type>
gen_downto( value_type val) {
return gen_downto_t<value_type>( val);
}
}}}}
#endif

View File

@ -0,0 +1,100 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_INDIRECT_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_INDIRECT_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <boost/iterator/indirect_iterator.hpp>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
struct no_type {};
template< class x> struct is_no_type_finder { BOOST_STATIC_CONSTANT(bool, is = false); };
template<> struct is_no_type_finder<no_type> { BOOST_STATIC_CONSTANT(bool, is = true); };
template< class r, class v_type>
struct indirect_iterator_finder {
BOOST_STATIC_CONSTANT(bool, is_notype = ::CGAL::PDB::internal::rangelib::detail::is_no_type_finder<v_type>::is );
typedef typename ::CGAL::PDB::internal::rangelib::range_finder<r>::range_type r_type;
typedef typename r_type::iterator i_type;
typedef typename ::boost::mpl::if_c< is_notype,
::boost::indirect_iterator<i_type>,
::boost::indirect_iterator<i_type, v_type>
>::type indirect_type;
};
}
template< class r, class v_type = ::CGAL::PDB::internal::rangelib::detail::no_type >
struct indirected_range : public irange< typename ::CGAL::PDB::internal::rangelib::detail::indirect_iterator_finder<r,v_type>::indirect_type > {
typedef irange< typename ::CGAL::PDB::internal::rangelib::detail::indirect_iterator_finder<r,v_type>::indirect_type > base;
typedef typename ::CGAL::PDB::internal::rangelib::detail::indirect_iterator_finder<r,v_type>::i_type old_iterator;
typedef typename ::CGAL::PDB::internal::rangelib::detail::indirect_iterator_finder<r,v_type>::indirect_type new_iterator;
indirected_range( old_iterator first, old_iterator last)
: base( new_iterator(first), new_iterator(last) ) {
}
indirected_range( r & rng)
: base( new_iterator( rng.begin() ),
new_iterator( rng.end() ) ) {
}
};
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class r> inline indirected_range<const r>
indirected( const r & rng) {
return indirected_range<const r>( rng.begin(), rng.end());
}
#endif
template< class r> inline indirected_range<r>
indirected( r & rng) {
return indirected_range<r>( rng.begin(), rng.end());
}
// here, you specify the value_type directly
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class v_type, class r> inline indirected_range<const r, v_type>
indirected( const r & rng, v_type* = 0) {
return indirected_range<const r, v_type>( rng.begin(), rng.end());
}
#endif
template< class v_type, class r> inline indirected_range<r, v_type>
indirected( r & rng, v_type* = 0) {
return indirected_range<r, v_type>( rng.begin(), rng.end());
}
}}}}
#endif

View File

@ -0,0 +1,24 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_MULTI_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_MULTI_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/multi_byeach.hpp>
#include <CGAL/PDB/internal/rangelib/multi_byrange.hpp>
#endif

View File

@ -0,0 +1,130 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_MULTI_BYEACH_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_MULTI_BYEACH_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <boost/iterator.hpp>
#include <CGAL/PDB/internal/rangelib/priv/rng_fun.hpp>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
template< class r, class multirange_function>
struct multi_byeach_iterator : public ::boost::iterator<
::std::input_iterator_tag,
typename first_argument_finder<multirange_function>::argument_type > {
typedef multi_byeach_iterator<r,multirange_function> self_type;
typedef typename range_finder<r>::range_type range;
typedef typename range::iterator iterator;
typedef typename range::value_type src_value_type;
typedef typename first_argument_finder<multirange_function>::argument_type dest_value_type;
multi_byeach_iterator( iterator first, iterator last, multirange_function f)
: m_f( f),
m_first( first), m_last( last),
m_val(),
m_idx( 0),
m_processed_last( first == last) {
compute_value();
}
self_type& operator++() {
compute_value();
return *this;
}
self_type operator++(int) {
self_type tmp( *this);
++*this;
return tmp;
}
const dest_value_type& operator*() const { return m_val; }
const dest_value_type* operator->() const { return &m_val; }
bool more() const { return (m_first != m_last) || !m_processed_last; }
private:
void compute_value() {
if ( m_first == m_last) {
m_processed_last = true;
return;
}
if ( m_f( m_val, *m_first, m_idx)) {
++m_idx;
return;
}
else
++m_first;
}
private:
multirange_function m_f;
iterator m_first, m_last;
dest_value_type m_val;
int m_idx;
// has the last element been processed?
bool m_processed_last;
};
template<class r, class f>
inline bool operator==( const multi_byeach_iterator<r,f> & first, const multi_byeach_iterator<r,f> & second) {
return first.more() == second.more();
}
template<class r, class f>
inline bool operator!=( const multi_byeach_iterator<r,f> & first, const multi_byeach_iterator<r,f> & second) {
return first.more() != second.more();
}
}
template< class r, class multirange_function>
struct multi_byeach_range : public irange< ::CGAL::PDB::internal::rangelib::detail::multi_byeach_iterator<r,multirange_function> > {
typedef ::CGAL::PDB::internal::rangelib::detail::multi_byeach_iterator<r,multirange_function> new_iterator;
typedef irange<new_iterator> base;
multi_byeach_range( r & rng, multirange_function f)
: base( new_iterator( rng.begin(), rng.end(), f),
new_iterator( rng.end(), rng.end(), f) ) {}
};
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template<class r, class f>
multi_byeach_range<const r,f> multied_byeach( const r & rng, f func) {
return multi_byeach_range<const r,f>(rng,func);
}
#endif
template<class r, class f>
multi_byeach_range<r,f> multied_byeach( r & rng, f func) {
return multi_byeach_range<r,f>(rng,func);
}
}}}}
#endif

View File

@ -0,0 +1,175 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_MULTI_BYRNG_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_MULTI_BYRNG_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <boost/iterator.hpp>
#include <CGAL/PDB/internal/rangelib/priv/rng_fun.hpp>
#include <vector>
#include <iterator>
#include <functional>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
template< class type> struct copy_ptr
{
public:
copy_ptr( const copy_ptr<type> & other) : m_pType( other.copy()) {
}
copy_ptr< type> & operator=( const copy_ptr< type> & other) {
type * copy = m_pType;
m_pType = 0;
delete copy;
m_pType = other.copy();
}
copy_ptr( type * pType = 0) : m_pType( pType) {}
~copy_ptr() { delete m_pType; }
type * get() const { return m_pType; }
private:
type * copy() const { return m_pType ? new type(*m_pType) : 0; }
private:
type * m_pType;
};
template< class f> struct multirange_function_finder {
typedef typename f::result_type result_type;
typedef typename result_type::value_type value_type;
};
// FIXME recalculate ALL iterator tags; for instance, in this case, we can have a forward iterator.
template< class r, class multirange_function>
struct multi_byrange_iterator : public ::boost::iterator<
::std::input_iterator_tag,
typename multirange_function_finder<multirange_function>::value_type > {
typedef multi_byrange_iterator<r,multirange_function> self_type;
typedef typename multirange_function_finder<multirange_function>::result_type result_range_type;
typedef typename result_range_type::value_type result_value_type;
typedef typename range_finder<r>:: range_type source_range_type;
typedef typename source_range_type::iterator iterator_type;
multi_byrange_iterator( iterator_type first, iterator_type last, multirange_function f)
: m_f( f),
m_first( first), m_last( last),
m_result(first != last ? new result_range_type( m_f(*m_first++)) : 0) {
if ( m_result.get())
if ( !*m_result.get() )
// the first element contained an empty range
compute_value();
}
self_type& operator++() {
compute_value();
return *this;
}
self_type operator++(int) {
self_type tmp( *this);
++*this;
return tmp;
}
const result_value_type& operator*() const { return **m_result.get(); }
const result_value_type* operator->() const { return &**m_result.get(); }
bool more() const {
return m_result.get() && *m_result.get();
}
private:
void compute_value() {
if ( m_result.get() == 0)
return; // the original range was empty
if ( *m_result.get())
++*m_result.get();
while ( !*m_result.get() && (m_first != m_last))
*m_result.get() = m_f( *m_first++);
}
private:
// IMPORTANT: order counts, see initialization in constructor
multirange_function m_f;
iterator_type m_first, m_last;
copy_ptr<result_range_type> m_result;
};
template<class r, class f>
inline bool operator==( const multi_byrange_iterator<r,f> & first, const multi_byrange_iterator<r,f> & second) {
return first.more() == second.more();
}
template<class r, class f>
inline bool operator!=( const multi_byrange_iterator<r,f> & first, const multi_byrange_iterator<r,f> & second) {
return first.more() != second.more();
}
}
template< class r, class multirange_function>
struct multi_byrange_range : public irange< ::CGAL::PDB::internal::rangelib::detail::multi_byrange_iterator<r,multirange_function> > {
typedef ::CGAL::PDB::internal::rangelib::detail::multi_byrange_iterator<r,multirange_function> new_iterator;
typedef irange<new_iterator> base;
multi_byrange_range( r & rng, multirange_function f)
: base( new_iterator( rng.begin(), rng.end(), f),
new_iterator( rng.end(), rng.end(), f) ) {}
};
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template<class r, class f>
multi_byrange_range<const r,f> multied_byrange( const r & rng, f func) {
return multi_byrange_range<const r,f>(rng,func);
}
template<class r, class res, class arg>
multi_byrange_range<const r, ::std::pointer_to_unary_function<arg,res> > multied_byrange_f( const r & rng, res (*func)(arg) ) {
typedef ::std::pointer_to_unary_function<arg,res> ptr;
return multi_byrange_range<const r, ptr>(rng, ptr(func) );
}
#endif
template<class r, class f>
multi_byrange_range<r,f> multied_byrange( r & rng, f func) {
return multi_byrange_range<r,f>(rng,func);
}
// stupid VC6 again, can't find the right overload, for a function
template<class r, class res, class arg>
multi_byrange_range<r, ::std::pointer_to_unary_function<arg,res> > multied_byrange_f( r & rng, res (*func)(arg) ) {
typedef ::std::pointer_to_unary_function<arg,res> ptr;
return multi_byrange_range<r, ptr>(rng, ptr(func) );
}
}}}}
#endif

View File

@ -0,0 +1,51 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_DEFS_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_DEFS_HPP_INCLUDED
#include <boost/config.hpp>
#if defined(BOOST_MSVC) || \
defined(BOOST_INTEL)
# if _MSC_VER <= 1200
# define CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
# endif
#endif
/*
Does the following compile?
template< class T> void f( T val) {}
template< class Res, class Arg> void f( Res (*func)(Arg) ) { }
void test( int) {}
int main(int argc, char* argv[]) {
f( &test);
}
*/
#define CGAL_PDB_BOOST_RTL_ALLOWS_OVERLOAD_BY_FUNC_PARAM
#ifdef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
// what else is new? ;)
#undef CGAL_PDB_BOOST_RTL_ALLOWS_OVERLOAD_BY_FUNC_PARAM
#endif
#endif

View File

@ -0,0 +1,206 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_RNGFUN_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_RNGFUN_HPP_INCLUDED
#include <boost/config.hpp>
namespace CGAL { namespace PDB { namespace internal { namespace rangelib { namespace rng {
/*
The following will fail to compile, if your compiler does not support partial specialization.
void add_item_summary( item_summary & summary, sold_items_info & info);
....
rng::for_each( sliced_byeach(v, ptr_fun(add_item_summary), slice_into_days),
show_item_summary);
Use this instead:
rng::for_each( sliced_byeach(v, rng::fun(add_item_summary), slice_into_days),
^^^^^^^^
show_item_summary);
*/
// note: we need the type of Arg1, without the reference
//
// Example: 'int&' -> 'int'
// (compilers that don't support partial specialization, can't do this)
template<class Arg1, class Arg2, class result>
struct fun_t2_base {
typedef Arg1 first_argument_type;
typedef result (*func)(Arg1&,Arg2);
fun_t2_base( func f) : m_f(f) {}
result operator()( Arg1 & arg1, Arg2 arg2) const {
return m_f( arg1, arg2);
}
func m_f;
};
template<class Arg1, class Arg2, class Arg3, class result>
struct fun_t3_base {
typedef Arg1 first_argument_type;
typedef result (*func)(Arg1&,Arg2,Arg3);
fun_t3_base( func f) : m_f(f) {}
result operator()( Arg1 & arg1, Arg2 arg2, Arg3 arg3) const {
return m_f( arg1, arg2, arg3);
}
func m_f;
};
template<class Arg1, class Arg2>
struct void_fun_t2_base {
typedef Arg1 first_argument_type;
typedef void (*func)(Arg1&,Arg2);
void_fun_t2_base( func f) : m_f(f) {}
void operator()( Arg1 & arg1, Arg2 arg2) const {
m_f( arg1, arg2);
}
func m_f;
};
template<class Arg1, class Arg2, class Arg3>
struct void_fun_t3_base {
typedef Arg1 first_argument_type;
typedef void (*func)(Arg1&,Arg2,Arg3);
void_fun_t3_base( func f) : m_f(f) {}
void operator()( Arg1 & arg1, Arg2 arg2, Arg3 arg3) const {
m_f( arg1, arg2, arg3);
}
func m_f;
};
namespace detail {
template< class T> struct fun_finder_impl {
template< class arg1, class arg2> struct fun2_type {
typedef fun_t2_base<arg1,arg2,T> result;
};
template< class arg1, class arg2, class arg3> struct fun3_type {
typedef fun_t3_base<arg1,arg2,arg3,T> result;
};
};
template<> struct fun_finder_impl<void> {
template< class arg1, class arg2> struct fun2_type {
typedef void_fun_t2_base<arg1,arg2> result;
};
template< class arg1, class arg2, class arg3> struct fun3_type {
typedef void_fun_t3_base<arg1,arg2,arg3> result;
};
};
template<class result, class arg1, class arg2> struct fun_finder2 {
typedef fun_finder_impl<result> finder_impl_type;
typedef typename finder_impl_type::template fun2_type<arg1,arg2> finder_type;
typedef typename finder_type::result type;
};
template<class result, class arg1, class arg2, class arg3> struct fun_finder3 {
typedef fun_finder_impl<result> finder_impl_type;
typedef typename finder_impl_type::template fun3_type<arg1,arg2,arg3> finder_type;
typedef typename finder_type::result type;
};
}
template<class Arg1, class Arg2, class result>
struct fun_t2 : public detail::fun_finder2<result,Arg1,Arg2>::type {
typedef typename detail::fun_finder2<result,Arg1,Arg2>::type base;
/*
painfully discovering once again that VC6 ***** big time
template< class func> fun_t2( func f) : base(f) {
}
*/
typedef result (*func)(Arg1&,Arg2);
fun_t2( func f) : base(f) {
}
};
template<class Arg1, class Arg2, class Arg3, class result>
struct fun_t3 : public detail::fun_finder3<result,Arg1,Arg2,Arg3>::type {
typedef typename detail::fun_finder3<result,Arg1,Arg2,Arg3>::type base;
typedef result (*func)(Arg1&,Arg2,Arg3);
fun_t3( func f) : base(f) {
}
};
/*
VC6 users
(may God have mercy on you;) )
Because VC6 chokes (amongst many others) on this:
template<class Arg1, class Arg2> inline void fun( void (pf)(Arg1&, Arg2) ) {}
void f(int&, long) {}
int main(int argc, char* argv[]) {
fun(&f);
}
You should use func<reference_type>
(specify the reference type).
The above should become
int main(int argc, char* argv[]) {
fun<int>(&f);
}
*/
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template<class Arg1, class Arg2, class result> inline
fun_t2<Arg1,Arg2,result> fun( result (*pf)(Arg1&, Arg2) ) {
return fun_t2<Arg1,Arg2,result>(pf);
}
#else
template<class Arg, class Arg1, class Arg2, class result> inline
fun_t2<Arg,Arg2,result> fun( result (*pf)(Arg1, Arg2) ) {
return fun_t2<Arg,Arg2,result>(pf);
}
#endif
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template<class Arg1, class Arg2, class Arg3, class result> inline
fun_t3<Arg1,Arg2,Arg3,result> fun( result (*pf)(Arg1&, Arg2, Arg3) ) {
return fun_t3<Arg1,Arg2,Arg3,result>(pf);
}
#else
template<class Arg, class Arg1, class Arg2, class Arg3, class result> inline
fun_t3<Arg,Arg2,Arg3,result> fun( result (*pf)(Arg1, Arg2, Arg3) ) {
return fun_t3<Arg,Arg2,Arg3,result>(pf);
}
#endif
}}}}}
#endif

View File

@ -0,0 +1,212 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef BOOST_TRAITS_HPP_INCLUDED
#define BOOST_TRAITS_HPP_INCLUDED
//#include <boost/mpl/aux_/has_xxx.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/mpl/if.hpp>
#include <iterator>
#include <boost/type_traits/ice.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_pointer.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <stddef.h> // for size_t
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
// creates classes has_iterator_category & has_value_type
BOOST_MPL_HAS_XXX_TRAIT_DEF( iterator_category)
BOOST_MPL_HAS_XXX_TRAIT_DEF( value_type)
BOOST_MPL_HAS_XXX_TRAIT_DEF( reference)
BOOST_MPL_HAS_XXX_TRAIT_DEF( is_range_type)
BOOST_MPL_HAS_XXX_TRAIT_DEF( key_type)
// allow extracting information from a given type
struct get_container_details_const {
template< class container_type> struct underlying_type {
typedef typename container_type::const_iterator iterator;
// moved const
typedef const typename container_type::reference reference;
typedef const typename container_type::value_type value_type;
typedef value_type* pointer;
// typedef iterator const_iterator;
// typedef reference const_reference;
// typedef pointer const_pointer;
//typedef typename container_type::const_pointer pointer;
};
};
struct get_container_details {
template< class container_type> struct underlying_type {
typedef typename container_type::iterator iterator;
typedef typename container_type::reference reference;
typedef typename container_type::value_type value_type;
//typedef typename container_type::pointer pointer;
typedef value_type* pointer;
// typedef typename container_type::const_iterator const_iterator;
// typedef typename container_type::const_reference const_reference;
// typedef typename container_type::const_pointer const_pointer;
};
};
struct get_ptr_details {
template< class ptr_type> struct underlying_type {
typedef ptr_type iterator;
#ifdef __BORLANDC__
typedef /* typename */ ::boost::remove_pointer<ptr_type>::type value_type;
#else /* ? __BORLANDC__ */
typedef typename ::boost::remove_pointer<ptr_type>::type value_type;
#endif /* __BORLANDC__ */
typedef value_type & reference;
typedef value_type * pointer;
// typedef const iterator const_iterator;
// typedef const reference const_reference;
// typedef const pointer const_pointer;
};
};
struct get_iterator_details {
struct has_ref_ptr {
template< class i_type> struct find {
typedef typename i_type::reference reference;
typedef typename i_type::pointer pointer;
};
};
struct has_no_ref_ptr {
template< class i_type> struct find {
typedef typename i_type::value_type value_type;
typedef value_type& reference;
typedef value_type* pointer;
};
};
template< class i_type> struct underlying_type {
typedef typename i_type::value_type value_type;
#if !defined(CGAL_PDB_BOOST_RTL_WORKAROUND_VC6)
// FIXME if value_type is const, append const to the reference and pointer
typedef typename i_type::reference reference;
typedef typename i_type::pointer pointer;
#else
// VC6 - default STL implementation does not have these defined
//
// however, note the our filter iterators have these defined;
// if so, use them
BOOST_STATIC_CONSTANT( bool, has_ref = ::CGAL::PDB::internal::rangelib::detail::has_reference< i_type>::value);
typedef typename ::boost::mpl::if_c< has_ref,
::CGAL::PDB::internal::rangelib::detail::get_iterator_details::has_ref_ptr, ::CGAL::PDB::internal::rangelib::detail::get_iterator_details::has_no_ref_ptr>::type refptr_find_type;
typedef typename refptr_find_type::template find<i_type>::reference reference;
typedef typename refptr_find_type::template find<i_type>::pointer pointer;
#endif
// typedef iterator const_iterator;
// typedef const reference const_reference;
// typedef const pointer const_pointer;
typedef i_type iterator;
};
};
template< class iterator_type>
class iterator_traits {
private:
BOOST_STATIC_CONSTANT( bool, is_ptr = ::boost::is_pointer< iterator_type>::value);
// * wrapper, so that we can derive from - needed by has_iterator_category/ has_value_type!
template< class any_type> struct wrapper {};
// * find if it's an iterator or a pointer
#ifdef __BORLANDC__
typedef ::boost::mpl::if_c< is_ptr,
#else /* ? __BORLANDC__ */
typedef typename ::boost::mpl::if_c< is_ptr,
#endif /* __BORLANDC__ */
::CGAL::PDB::internal::rangelib::detail::get_ptr_details, ::CGAL::PDB::internal::rangelib::detail::get_iterator_details >::type ask_type;
public:
typedef typename ask_type::template underlying_type< iterator_type>::iterator iterator;
typedef typename ask_type::template underlying_type< iterator_type>::value_type value_type;
typedef typename ask_type::template underlying_type< iterator_type>::reference reference;
typedef typename ask_type::template underlying_type< iterator_type>::pointer pointer;
typedef iterator const_iterator;
typedef reference const_reference;
};
template< class container_type >
class container_traits {
private:
BOOST_STATIC_CONSTANT( bool, is_c = ::boost::is_const< container_type>::value);
typedef typename ::boost::mpl::if_c< is_c,
::CGAL::PDB::internal::rangelib::detail::get_container_details_const,
::CGAL::PDB::internal::rangelib::detail::get_container_details>::type chosen_type;
public:
typedef typename chosen_type::template underlying_type< container_type>::iterator iterator;
typedef typename chosen_type::template underlying_type< container_type>::value_type value_type;
typedef typename chosen_type::template underlying_type< container_type>::reference reference;
typedef typename chosen_type::template underlying_type< container_type>::pointer pointer;
};
}
// forward declaration
template< class container_type> struct crange;
// finds the real range type, given a range/ container or const container
template< class r>
struct range_finder {
typedef typename ::boost::remove_const<r>::type nonconst_r;
BOOST_STATIC_CONSTANT( bool, is_range = ::CGAL::PDB::internal::rangelib::detail::has_is_range_type<nonconst_r>::value);
typedef typename ::boost::mpl::if_c< is_range, nonconst_r, ::CGAL::PDB::internal::rangelib::crange<r> >::type range_type;
typedef typename range_type::iterator iterator_type;
typedef typename ::std::iterator_traits<iterator_type>::difference_type difference_type;
};
namespace detail {
template< class function>
struct first_argument_finder {
// FIXME - in the future, allow function to be a C++ function,
// which I will automatically wrap into a binary_function (partial specialization)
typedef typename function::first_argument_type ref_type;
typedef typename ::boost::remove_reference<ref_type>::type argument_type;
};
}
}}}}
#endif // CGAL_PDB_BOOST_RTL_HPP_INCLUDED

View File

@ -0,0 +1,274 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <utility> // for std::pair
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
/*
Purpose:
To save you as many keystrokes as possible, when dealing with
iterators/containers/algorithms,
so that you will write compact code that is easy and straightforward.
*/
// FIXME - create helpers for containers, like, to very simply access key-only or value-only
// range for containers
template< class container_type>
struct crange : public ::CGAL::PDB::internal::rangelib::detail::container_traits< container_type> {
private:
typedef ::CGAL::PDB::internal::rangelib::detail::container_traits< container_type> parent_class_type;
public:
typedef typename parent_class_type::iterator iterator;
typedef typename parent_class_type::reference reference;
typedef typename parent_class_type::pointer pointer;
typedef crange< container_type> self_type; // this class
// the type does not matter; I just want to know if a given type is a range or not
struct is_range_type {};
// * Construction
template< class cont>
crange( cont & c)
: m_first( c.begin() ), m_last( c.end() ) {
}
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class cont>
crange( const cont & c)
: m_first( c.begin() ), m_last( c.end() ) {
}
#endif
crange( iterator first, iterator last)
: m_first( first), m_last( last) {
}
crange( ::std::pair<iterator,iterator> val)
: m_first( val.first), m_last( val.second) {
}
// conversion
template< class r>
crange( const crange<r> & other)
: m_first( other.begin()), m_last( other.end()) {
}
// * Range access
iterator begin() const { return m_first; }
iterator end() const { return m_last; }
void begin( iterator first) { m_first = first; }
void end( iterator last) { m_last = last; }
/*
Use rng::advanced() instead!
// useful for algorithms that require some value in the middle of the range,
// like, nth_element or partial_sort
template< class Dist> iterator advanced(Dist n) const {
iterator i;
::std::advance( i, n);
return i;
}
*/
// * Operators
self_type & operator=( const self_type & other) {
m_first = other.m_first;
m_last = other.m_last;
return *this;
}
reference operator*() const { return *m_first; }
pointer operator->() const { return &*m_first; }
// FIXME - in the future, maybe allow checks on ranges (are they valid?)
// is the range valid (or we've reached the end) ?
operator bool() const {
return m_first != m_last;
}
self_type & operator++() {
++m_first;
return *this;
}
self_type operator++(int) {
self_type tmp = *this;
++*this;
return tmp;
}
self_type & operator--() {
--m_first;
return *this;
}
self_type operator--(int) {
self_type tmp = *this;
--*this;
return tmp;
}
self_type & operator+=( size_t n) {
m_first += n;
return *this;
}
self_type & operator-=( size_t n) {
m_first += n;
return *this;
}
reference operator[]( size_t n) {
return m_first[n];
}
// * Operators not implemented
// Note: it's dangerous to compare two ranges, and it makes no point
// in doing so.
// * it's not very straightforward when two ranges should be equal.
// (should r1.begin() == r2.begin() suffice?)
// * if we compare r1.begin() == r2.begin() && r1.end() == r2.end(),
// it might be inefficient.
//
// You can, however, compare two begin() iterators.
// You can do so, at will, very simple:
// if ( r1.begin() == r2.begin() )...
// (same for end)
bool operator !=( const self_type&) const;
bool operator ==( const self_type&) const;
bool operator <( const self_type&) const;
bool operator <=( const self_type&) const;
bool operator >( const self_type&) const;
bool operator >=( const self_type&) const;
void operator -( const self_type&) const;
private:
iterator m_first, m_last;
};
// * non-member Operators
template< class r> inline crange<r> operator+( crange<r> val, size_t n) {
return val += n;
}
template< class r> inline crange<r> operator+( size_t n, crange<r> val) {
return val += n;
}
template< class r> inline crange<r> operator-( crange<r> val, size_t n) {
return val -= n;
}
template< class r> inline crange<r> operator-( size_t n, crange<r> val) {
return val -= n;
}
namespace detail {
template< class iterator_type>
struct iterator_pair : public ::CGAL::PDB::internal::rangelib::detail::iterator_traits< iterator_type> {
private:
typedef ::CGAL::PDB::internal::rangelib::detail::iterator_traits< iterator_type> parent_class_type;
public:
typedef typename parent_class_type::iterator iterator;
iterator begin() const { return m_first; }
iterator end() const { return m_last; }
iterator_pair( iterator first, iterator last) : m_first( first), m_last( last) {}
private:
iterator m_first, m_last;
};
} // detail
// range for iterators
template< class iterator_type>
struct irange : public crange< detail::iterator_pair< iterator_type> > {
typedef detail::iterator_pair< iterator_type> pair_type;
typedef crange< pair_type > base;
typedef irange< iterator_type> self_type;
// end has a default value, for facilitating the 'default iterator is passed-end iterator' idiom
irange( iterator_type begin, iterator_type end = iterator_type())
: base( pair_type(begin,end) ) {}
#if !defined(BOOST_MSVC) || \
_MSC_VER >= 1300
template <typename T, size_t N>
irange( T (&ar)[N])
: base( pair_type(&ar[0], &ar[N]) )
{}
#endif /* _MSC_VER >= 1300 */
irange( const ::std::pair<iterator_type,iterator_type> & both)
: base( pair_type(both.first,both.second)) {
}
self_type & operator=( const self_type & other) {
base::operator=( other);
return *this;
}
};
// * converter functions - c_range & i_range
// (so that you don't have to create an irange<> unless necesary)
template< class container>
inline crange< container> c_range( container & c) {
return crange< container>( c);
}
template< class container>
inline crange< const container> c_range( const container & c) {
return crange< const container>( c);
}
template< class iterator>
inline irange< iterator> i_range( iterator first, iterator last) {
return irange< iterator>( first, last);
}
// C-like range
template< class iterator>
inline irange< iterator> i_range( iterator first, int n) {
// only works for random iterators (where operator + is implemented)
return irange< iterator>( first, first + n);
}
}}}}
#endif // CGAL_PDB_BOOST_RTL_HPP_INCLUDED

View File

@ -0,0 +1,173 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_RESORT_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_RESORT_HPP_INCLUDED
#include <boost/config.hpp>
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <CGAL/PDB/internal/rangelib/algo.hpp>
#include <CGAL/PDB/internal/rangelib/indirect.hpp>
#include <boost/shared_ptr.hpp>
#include <vector>
#include <functional>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
template< class r>
struct resort_iterator_finder {
typedef typename ::CGAL::PDB::internal::rangelib::range_finder<r>::range_type r_type;
typedef typename r_type::iterator i_type;
typedef typename r_type::value_type v_type;
typedef typename r_type::pointer pointer;
typedef typename r_type::reference reference;
typedef typename ::std::vector<pointer>::iterator indirected_i;
typedef ::boost::indirect_iterator<indirected_i > resort_type;
};
}
// FIXME - I should find a way to disallow shrinking;
// something like, disallow this:
// crange<whatever> r = resorted(x);
//
// the above is a bug, because the iterators returned from resorted range point to
// an INTERNAL vector, which is destructed at resorted_range's destruction
//
// TOTHINK - perhaps the best way is to simply disallow copy-construction???
// FIXME - the range should at least contain forward iterators
template< class r>
struct resorted_range : public irange< typename ::CGAL::PDB::internal::rangelib::detail::resort_iterator_finder<r>::resort_type > {
typedef irange< typename ::CGAL::PDB::internal::rangelib::detail::resort_iterator_finder<r>::resort_type> base;
typedef typename ::CGAL::PDB::internal::rangelib::detail::resort_iterator_finder<r>::i_type old_iterator;
typedef typename ::CGAL::PDB::internal::rangelib::detail::resort_iterator_finder<r>::resort_type new_iterator;
typedef typename ::CGAL::PDB::internal::rangelib::detail::resort_iterator_finder<r>::v_type v_type;
typedef typename ::CGAL::PDB::internal::rangelib::detail::resort_iterator_finder<r>::pointer pointer;
typedef typename ::CGAL::PDB::internal::rangelib::detail::resort_iterator_finder<r>::reference reference;
typedef std::vector< pointer> array;
resorted_range( old_iterator first, old_iterator last)
: base( new_iterator(), new_iterator() ),
m_resorted( new array) {
typedef ::std::less< v_type> default_sort;
resort( first, last, default_sort() );
}
template< class pred>
resorted_range( old_iterator first, old_iterator last, pred p)
: base( new_iterator(), new_iterator() ),
m_resorted( new array) {
resort( first, last, p );
}
resorted_range( r & rng)
: base( new_iterator(),
new_iterator() ),
m_resorted( new array) {
typedef ::std::less< v_type> default_sort;
resort( rng.begin(), rng.end(), default_sort());
}
template< class pred>
resorted_range( r & rng, pred p )
: base( new_iterator(),
new_iterator() ),
m_resorted( new array) {
resort( rng.begin(), rng.end(), p );
}
private:
struct resorted_inserter {
resorted_inserter( array & v) : m_v( v) {}
void operator()( reference val) {
m_v.push_back( &val);
}
private:
array & m_v;
};
template< class pred>
struct dereference_ptr {
dereference_ptr( pred p ) : m_p(p) {}
bool operator() (pointer first, pointer second) {
return m_p( *first, *second);
}
private:
pred m_p;
};
template<class pred>
void resort( old_iterator first, old_iterator last, pred p) {
m_resorted->reserve( ::std::distance(first, last) );
::std::for_each( first, last, resorted_inserter( *m_resorted) );
::CGAL::PDB::internal::rangelib::rng::sort( *m_resorted, dereference_ptr<pred>(p) );
// reset the iterators
begin( m_resorted->begin() );
end( m_resorted->end() );
}
private:
::boost::shared_ptr<array> m_resorted;
};
// resorts using "operator<"
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class r> inline resorted_range<const r>
resorted( const r & rng) {
return resorted_range<const r>( rng.begin(), rng.end() );
}
#endif
template< class r> inline resorted_range<r>
resorted( r & rng) {
return resorted_range<r>( rng.begin(), rng.end() );
}
// using binary predicate
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class r, class pred> inline resorted_range<const r>
resorted( const r & rng, pred p) {
return resorted_range<const r>( rng.begin(), rng.end(), p );
}
#endif
template< class r, class pred> inline resorted_range<r>
resorted( r & rng, pred p) {
return resorted_range<r>( rng.begin(), rng.end(), p );
}
}}}}
#endif

View File

@ -0,0 +1,78 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_REVERSE_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_REVERSE_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <boost/iterator/reverse_iterator.hpp>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
template< class r>
struct reverse_iterator_finder {
typedef typename ::CGAL::PDB::internal::rangelib::range_finder<r>::range_type r_type;
typedef typename r_type::iterator i_type;
typedef ::boost::reverse_iterator<i_type> reverse_type;
};
}
template< class r >
struct reversed_range : public irange< typename ::CGAL::PDB::internal::rangelib::detail::reverse_iterator_finder<r>::reverse_type > {
typedef irange< typename ::CGAL::PDB::internal::rangelib::detail::reverse_iterator_finder<r>::reverse_type > base;
typedef typename ::CGAL::PDB::internal::rangelib::detail::reverse_iterator_finder<r>::i_type old_iterator;
typedef typename ::CGAL::PDB::internal::rangelib::detail::reverse_iterator_finder<r>::reverse_type new_iterator;
reversed_range( old_iterator first, old_iterator last)
: base( new_iterator(last), new_iterator(first) ) {
}
reversed_range( r & rng)
: base( new_iterator( rng.end() ),
new_iterator( rng.begin() ) ) {
}
};
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class r> inline reversed_range<const r>
reversed( const r & rng) {
return reversed_range<const r>( rng.begin(), rng.end() );
}
#endif
template< class r> inline reversed_range<r>
reversed( r & rng) {
return reversed_range<r>( rng.begin(), rng.end() );
}
}}}}
#endif

View File

@ -0,0 +1,25 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_SLICE_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_SLICE_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/slice_byeach.hpp>
#include <CGAL/PDB/internal/rangelib/slice_byrng.hpp>
#endif

View File

@ -0,0 +1,178 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_SLICEBYEACH_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_SLICEBYEACH_HPP_INCLUDED
#include "boost/config.hpp"
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <boost/iterator.hpp>
#include <functional>
#include <CGAL/PDB/internal/rangelib/priv/rng_fun.hpp>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
// slices, by querying each element once at a time;
// useful for input iterator ranges (where you cannot access
// two elements at a time)
//
// VERY IMPORTANT:
// You should understand that each sclice is made of at least ONE element from the
// original slice. In case you want intermediate "slices", you should use multi_range
//
//
//
// note: the byeach_function should be a binary functor, taking 2 arguments:
// arg1 - the result type (what we return for a slice of the range)
// arg2 - one value from the slice
// It has to have the 'first_argument_type' defined (a typedef, most likely)
//
// if f is a byeach_function, then
// f( result, val);
// will recompute the result based on val
// For each value 'val' from a slice, we'll have a call to f(result,val);
template< class r, class byeach_function, class slicer>
struct slice_byeach_iterator : public ::boost::iterator<
::std::input_iterator_tag,
typename first_argument_finder<byeach_function>::argument_type > {
typedef slice_byeach_iterator<r,byeach_function, slicer> self_type;
typedef typename range_finder<r>::range_type range;
typedef typename range::iterator iterator;
typedef typename range::value_type src_value_type;
typedef typename first_argument_finder<byeach_function>::argument_type dest_value_type;
slice_byeach_iterator( iterator first, iterator last, byeach_function f, slicer s, dest_value_type init)
: m_f( f), m_slicer( s),
m_first( first), m_last( last),
m_init( init), m_val( init),
m_processed_last( first == last) {
compute_value();
}
self_type& operator++() {
compute_value();
return *this;
}
self_type operator++(int) {
self_type tmp( *this);
++*this;
return tmp;
}
const dest_value_type& operator*() const { return m_val; }
const dest_value_type* operator->() const { return &m_val; }
bool more() const { return (m_first != m_last) || !m_processed_last; }
private:
void compute_value() {
if ( m_first == m_last) {
m_processed_last = true;
return;
}
// FIXME for iterator categories > input_iterator
// don't use any temporary
m_val = m_init;
while ( true) {
src_value_type tmp = *m_first;
m_f( m_val, tmp);
++m_first;
if ( m_first != m_last) {
if ( !m_slicer( tmp, *m_first))
// got to a new slice
break;
}
else
// got to the end
break;
}
}
private:
byeach_function m_f;
slicer m_slicer;
iterator m_first, m_last;
dest_value_type m_init, m_val;
// has the last sliced element been processed?
bool m_processed_last;
};
template<class r, class f, class s>
inline bool operator==( const slice_byeach_iterator<r,f,s> & first, const slice_byeach_iterator<r,f,s> & second) {
return first.more() == second.more();
}
template<class r, class f, class s>
inline bool operator!=( const slice_byeach_iterator<r,f,s> & first, const slice_byeach_iterator<r,f,s> & second) {
return first.more() != second.more();
}
}
template< class r, class byeach_function, class slicer>
struct sliced_byeach_range : public irange< ::CGAL::PDB::internal::rangelib::detail::slice_byeach_iterator<r,byeach_function,slicer> > {
typedef ::CGAL::PDB::internal::rangelib::detail::slice_byeach_iterator<r,byeach_function,slicer> iterator_type;
typedef irange< iterator_type> base;
typedef typename iterator_type::dest_value_type v_type;
sliced_byeach_range( r & rng, byeach_function f, slicer s, v_type init = v_type() )
: base( iterator_type( rng.begin(), rng.end(), f, s, init),
iterator_type( rng.end(), rng.end(), f, s, init)) {}
};
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class r, class f, class s, class initializer> inline sliced_byeach_range<const r,f,s>
sliced_byeach( const r & rng, f func, s slicer, initializer init) {
return sliced_byeach_range<const r,f,s>( rng, func, slicer, init);
}
template< class r, class f, class s> inline sliced_byeach_range<const r,f,s>
sliced_byeach( const r & rng, f func, s slicer) {
return sliced_byeach_range<const r,f,s>( rng, func, slicer);
}
#endif
template< class r, class f, class s, class initializer> inline sliced_byeach_range<r,f,s>
sliced_byeach( r & rng, f func, s slicer, initializer init) {
return sliced_byeach_range<r,f,s>( rng, func, slicer, init);
}
template< class r, class f, class s> inline sliced_byeach_range<r,f,s>
sliced_byeach( r & rng, f func, s slicer) {
return sliced_byeach_range<r,f,s>( rng, func, slicer);
}
}}}}
#endif

View File

@ -0,0 +1,177 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_SLICEBRNG_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_SLICEYRNG_HPP_INCLUDED
#include "boost/config.hpp"
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <functional>
#include <CGAL/PDB/internal/rangelib/priv/rng_fun.hpp>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
/*
FIXME
sliced() - allow for a transformation that will do this:
from a given range, slice multiple consecutive records, into only ONE record
(of a certain type).
TOTHINK
allow for two types of slices:
One that allows to work on one element at a time, and
one that allows to work on a range at a time (takes a range, and returns one value)
Example: you take a string, and return its words (also, quoted text is treated as one word).
[TOTHINK]
also, allow to somehow, for a range, to return multiple values.
For example, if we're generating a daily report for one month.
For some days, we have no activity (therefore, no records). We would like to
create some "empty" records to specify that.
Maybe this could just be another type of range. YUP:
We'll have a range that takes two elements. Given these, it returns as many other
elements as possible.
*/
namespace detail {
// slices, by querying each element once at a time;
// useful for input iterator ranges (where you cannot access
// two elements at a time)
//
// VERY IMPORTANT:
// You should understand that each slice is made of at least ONE element from the
// original slice. In case you want intermediate "slices", you should use multirng
//
//
//
// note: the byrng_function should be a functor taking three arguments
// arg1 - the result type (what we return for a slice of the range)
// arg2 & arg3 - the iterators that represent a slice
// It has to have 'result_type' defined (what you're returning)
// result_type must be default-constructible
template< class r, class byrng_function, class slicer>
struct slice_byrange_iterator : public ::boost::iterator<
::std::input_iterator_tag,
typename first_argument_finder<byrng_function>::argument_type > {
typedef slice_byrange_iterator<r,byrng_function, slicer> self_type;
typedef typename range_finder<r>::range_type range_type;
typedef typename range_type::iterator iterator_type;
typedef typename first_argument_finder<byrng_function>::argument_type result_type;
slice_byrange_iterator( iterator_type first, iterator_type last, byrng_function f, slicer s)
: m_f( f), m_slicer( s),
m_first( first), m_last( last),
m_val( result_type() ),
m_processed_last( first == last) {
compute_value();
}
self_type& operator++() {
compute_value();
return *this;
}
self_type operator++(int) {
self_type tmp( *this);
++*this;
return tmp;
}
const result_type& operator*() const { return m_val; }
const result_type* operator->() const { return &m_val; }
bool more() const { return (m_first != m_last) || !m_processed_last; }
private:
void compute_value() {
if ( m_first == m_last) {
m_processed_last = true;
return;
}
iterator_type begin = m_first;
while ( m_first != m_last) {
iterator_type prev = m_first;
++m_first;
if ( m_first == m_last)
break;
if ( !m_slicer( *prev, *m_first))
break;
}
m_f( m_val, begin, m_first);
}
private:
byrng_function m_f;
slicer m_slicer;
iterator_type m_first, m_last;
result_type m_val;
// has the last sliced element been processed?
bool m_processed_last;
};
template<class r, class f, class s>
inline bool operator==( const slice_byrange_iterator<r,f,s> & first, const slice_byrange_iterator<r,f,s> & second) {
return first.more() == second.more();
}
template<class r, class f, class s>
inline bool operator!=( const slice_byrange_iterator<r,f,s> & first, const slice_byrange_iterator<r,f,s> & second) {
return first.more() != second.more();
}
}
template< class r, class byrng_function, class slicer>
struct sliced_byrange_range : public irange< ::CGAL::PDB::internal::rangelib::detail::slice_byrange_iterator<r,byrng_function,slicer> > {
typedef ::CGAL::PDB::internal::rangelib::detail::slice_byrange_iterator<r,byrng_function,slicer> iterator_type;
typedef irange< iterator_type> base;
sliced_byrange_range( r & rng, byrng_function f, slicer s )
: base( iterator_type( rng.begin(), rng.end(), f, s),
iterator_type( rng.end(), rng.end(), f, s)) {}
};
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class r, class f, class s> inline sliced_byrange_range<const r,f,s>
sliced_byrange( const r & rng, f func, s slicer) {
return sliced_byrange_range<const r,f,s>( rng, func, slicer);
}
#endif
template< class r, class f, class s> inline sliced_byrange_range<r,f,s>
sliced_byrange( r & rng, f func, s slicer) {
return sliced_byrange_range<r,f,s>( rng, func, slicer);
}
}}}}
#endif

View File

@ -0,0 +1,207 @@
// Boost. Iterable Range Library (rangelib)
//
// Copyright 2003-2004 John Torjo (john@torjo.com) and Matthew Wilson (matthew@synesis.com.au)
//
// Permission to copy, use, sell and distribute this software is granted
// provided this copyright notice appears in all copies.
// Permission to modify the code and to distribute modified code is granted
// provided this copyright notice appears in all copies, and a notice
// that the code was modified is included with the copyright notice.
//
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef CGAL_PDB_BOOST_RTL_TRANSFORM_HPP_INCLUDED
#define CGAL_PDB_BOOST_RTL_TRANSFORM_HPP_INCLUDED
#include <CGAL/PDB/internal/rangelib/priv/defs.hpp>
#include <CGAL/PDB/internal/rangelib/priv/traits.hpp>
#include <CGAL/PDB/internal/rangelib/range.hpp>
#include <boost/iterator/transform_iterator.hpp>
#include <functional>
// rangelib = Range Library
namespace CGAL { namespace PDB { namespace internal { namespace rangelib {
namespace detail {
template< class r, class function>
struct transform_iterator_finder {
typedef typename ::CGAL::PDB::internal::rangelib::range_finder<r>::range_type r_type;
typedef typename r_type::iterator i_type;
typedef ::boost::transform_iterator<function, i_type> transform_type;
};
}
template< class r, class function >
struct transformed_range : public irange< typename ::CGAL::PDB::internal::rangelib::detail::transform_iterator_finder<r,function>::transform_type > {
typedef irange< typename ::CGAL::PDB::internal::rangelib::detail::transform_iterator_finder<r,function>::transform_type> base;
typedef typename ::CGAL::PDB::internal::rangelib::detail::transform_iterator_finder<r,function>::i_type old_iterator;
typedef typename ::CGAL::PDB::internal::rangelib::detail::transform_iterator_finder<r,function>::transform_type new_iterator;
// transformed_range( old_iterator first, old_iterator last, function f)
// : base( new_iterator(first,f), new_iterator(last,f) ) {
//}
typedef typename base::iterator const_iterator;
transformed_range( r & rng, function f )
: base( new_iterator( rng.begin(),f ),
new_iterator( rng.end(),f ) ) {
}
};
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template< class r, class function> inline transformed_range<const r, function>
transformed( const r & rng, function f) {
// return transformed_range<const r, function>( rng.begin(), rng.end(), f);
return transformed_range<const r, function>( rng, f);
}
template< class r, class arg, class res> inline transformed_range<const r, ::std::pointer_to_unary_function<arg,res> >
transformed_f( const r & rng, res (*f)(arg) ) {
// return transformed_range<const r, ::std::pointer_to_unary_function<arg,res> >( rng.begin(), rng.end(),
// ::std::pointer_to_unary_function<arg,res>(f) );
return transformed_range<const r, ::std::pointer_to_unary_function<arg,res> >( rng,
::std::pointer_to_unary_function<arg,res>(f) );
}
#endif
template< class r, class function> inline transformed_range<r, function>
transformed( r & rng, function f) {
// return transformed_range<r, function>( rng.begin(), rng.end(), f);
return transformed_range<r, function>( rng, f);
}
// VC6 chokes if both these functions have the same name
template< class r, class arg, class res> inline transformed_range<r, ::std::pointer_to_unary_function<arg,res> >
transformed_f( r & rng, res (*f)(arg) ) {
// return transformed_range<r, ::std::pointer_to_unary_function<arg,res> >( rng.begin(), rng.end(),
// ::std::pointer_to_unary_function<arg,res>(f) );
return transformed_range<r, ::std::pointer_to_unary_function<arg,res> >( rng,
::std::pointer_to_unary_function<arg,res>(f) );
}
// FIXME explain usage
template< class r_and_f_finder> inline transformed_range<typename r_and_f_finder::range_type, typename r_and_f_finder::function_type>
transformed( const r_and_f_finder & val) {
return transformed( val.range(), val.function() );
}
// FIXME maybe select1st/select2nd from MPL can be used
template<class pair_type>
struct select_2nd {
BOOST_STATIC_CONSTANT( bool, is_const = ::boost::is_const<pair_type>::value);
typedef typename pair_type::second_type result_type_raw;
typedef typename ::boost::mpl::if_c<is_const, const result_type_raw, result_type_raw>::type result_type;
result_type & operator() ( pair_type & val) const { return val.second; }
};
template<class pair_type>
struct select_1st {
BOOST_STATIC_CONSTANT( bool, is_const = ::boost::is_const<pair_type>::value);
typedef typename pair_type::first_type result_type_raw;
typedef typename ::boost::mpl::if_c<is_const, const result_type_raw, result_type_raw>::type result_type;
result_type & operator() ( pair_type & val) const { return val.first; }
};
namespace detail {
template< class r_type, class transformer_type>
struct transform_helper {
typedef r_type range_type;
// this is so that, in case you're using the wrong (transformer) type,
// to get a compile-time error ASAP
typedef typename transformer_type::result_type result_type;
typedef transformer_type function_type;
range_type & range() const { return m_r; }
function_type function() const { return m_f; }
transform_helper( range_type & r, function_type f) : m_r(r), m_f(f) {}
private:
mutable range_type & m_r;
function_type m_f;
};
template< class collection> struct transform_key_finder {
BOOST_STATIC_CONSTANT( bool, is_const = ::boost::is_const<collection>::value);
typedef typename collection::value_type value_type_raw;
typedef typename ::boost::mpl::if_c<is_const,const value_type_raw, value_type_raw>::type value_type;
typedef select_1st<value_type> key_finder;
typedef transform_helper<collection,key_finder> type;
};
template< class collection> struct transform_value_finder {
BOOST_STATIC_CONSTANT( bool, is_const = ::boost::is_const<collection>::value);
typedef typename collection::value_type value_type_raw;
typedef typename ::boost::mpl::if_c<is_const,const value_type_raw, value_type_raw>::type value_type;
typedef select_2nd<value_type> value_finder;
typedef transform_helper<collection,value_finder> type;
};
}
// FIXME explain this in the docs ;)
/*
given a collection (or a sequence of pairs),
these allow you to easily grab either the first (the key) or the second,
and return a transformed range.
(a range of keys or a range of values)
*/
#ifndef CGAL_PDB_BOOST_RTL_WORKAROUND_VC6
template<class collection> inline typename ::CGAL::PDB::internal::rangelib::detail::transform_key_finder<const collection>::type
pair_1st( const collection & c) {
typedef typename ::CGAL::PDB::internal::rangelib::detail::transform_key_finder<const collection> finder;
typedef typename finder::type result_type;
typedef typename finder::key_finder key_finder;
return result_type(c, key_finder() );
}
template<class collection> inline typename ::CGAL::PDB::internal::rangelib::detail::transform_value_finder<const collection>::type
pair_2nd( const collection & c) {
typedef typename ::CGAL::PDB::internal::rangelib::detail::transform_value_finder<const collection> finder;
typedef typename finder::type result_type;
typedef typename finder::value_finder value_finder;
return result_type(c, value_finder() );
}
#endif
template<class collection> inline typename ::CGAL::PDB::internal::rangelib::detail::transform_key_finder<collection>::type
pair_1st( collection & c) {
typedef typename ::CGAL::PDB::internal::rangelib::detail::transform_key_finder<collection> finder;
typedef typename finder::type result_type;
typedef typename finder::key_finder key_finder;
return result_type(c, key_finder() );
}
template<class collection> inline typename ::CGAL::PDB::internal::rangelib::detail::transform_value_finder<collection>::type
pair_2nd( collection & c) {
typedef typename ::CGAL::PDB::internal::rangelib::detail::transform_value_finder<collection> finder;
typedef typename finder::type result_type;
typedef typename finder::value_finder value_finder;
return result_type(c, value_finder() );
}
// FIXME - make it possible to transform using a member
}}}}
#endif

View File

@ -24,35 +24,28 @@
#include <CGAL/PDB/Point.h>
#include <CGAL/PDB/Chain.h>
#include <CGAL/PDB/Monomer.h>
#include <CGAL/PDB/Heterogen.h>
#include <CGAL/PDB/PDB.h>
#include <boost/iterator/transform_iterator.hpp>
#include <boost/iterator/filter_iterator.hpp>
#include <boost/range.hpp>
#include <CGAL/PDB/internal/rangelib/filter.hpp>
#include <CGAL/PDB/internal/rangelib/transform.hpp>
#include <CGAL/PDB/internal/rangelib/algo.hpp>
#include <algorithm>
namespace CGAL { namespace PDB {
using internal::rangelib::rng::for_each;
using internal::rangelib::rng::copy;
//! boost changes from size to distance a 1.34, so use this
template <class Range>
unsigned int size(Range r) {
unsigned int distance(const Range &r) {
return std::distance(r.begin(), r.end());
}
template <class Range, class F>
const F& for_each(const Range& r, const F &f) {
CGAL_PDB_FOREACH(typename Range::iterator::reference v, r) {
f(v);
}
return f;
}
template <class Range, class F>
const F& for_each(Range& r, const F &f) {
CGAL_PDB_FOREACH(typename Range::iterator::reference v, r) {
f(v);
}
return f;
}
#define CGAL_PDB_GET_MAP(ucname, lcname) \
template <class From> \
struct Get_##lcname { \
@ -63,7 +56,7 @@ const F& for_each(Range& r, const F &f) {
}; \
template <class From2> \
struct Get_##lcname<const From2> { \
typedef const ucname& result_type; \
typedef const ucname& result_type; \
result_type operator()(From2 v) const { \
return v.lcname(); \
} \
@ -94,28 +87,27 @@ struct Get_index {
template <class A>
struct Get_key {
typedef typename A::Key result_type;
result_type operator()(A a) const {
result_type operator()(const A& a) const {
return a.key();
}
};
#define CGAL_PDB_MAKE_RANGE(ucname, lcname) \
template <class Range> \
boost::iterator_range<boost::transform_iterator< Get_##lcname<typename Range::iterator::reference> , typename Range::iterator> > \
make_##lcname##_range(const Range& r){ \
typedef boost::transform_iterator<Get_##lcname<typename Range::iterator::reference>, typename Range::iterator> Tr; \
return boost::make_iterator_range(Tr(r.begin(), Get_##lcname<typename Range::iterator::reference>()), \
Tr(r.end(), Get_##lcname<typename Range::iterator::reference>())); \
internal::rangelib::transformed_range<Range, Get_##lcname<typename Range::iterator::reference> > \
make_##lcname##_range( Range r){ \
return internal::rangelib::transformed(r, Get_##lcname<typename Range::iterator::reference>()); \
} \
/**
template <class Range> \
boost::iterator_range<boost::transform_iterator< Get_##lcname<typename Range::iterator::reference> , typename Range::iterator> > \
make_##lcname##_range(Range& r){ \
typedef boost::transform_iterator<Get_##lcname<typename Range::iterator::reference>, typename Range::iterator> Tr; \
return boost::make_iterator_range(Tr(r.begin(), Get_##lcname<typename Range::iterator::reference>()), \
Tr(r.end(), Get_##lcname<typename Range::iterator::reference>())); \
internal::rangelib::transformed_range<Range, Get_##lcname<const typename Range::iterator::reference> > \
make_##lcname##_range(const Range& r){ \
return internal::rangelib::transformed(r, Get_##lcname<const typename Range::iterator::reference>()); \
} \
*/
CGAL_PDB_MAKE_RANGE(Atom, atom);
CGAL_PDB_MAKE_RANGE(Monomer, monomer);
CGAL_PDB_MAKE_RANGE(Chain, chain);
@ -144,11 +136,9 @@ struct Get_bond_indices {
//! Return an iterator range which returns a pair of indices for a bond
template <class Range>
boost::iterator_range<boost::transform_iterator<Get_bond_indices, typename Range::iterator> >
internal::rangelib::transformed_range<Range, Get_bond_indices>
make_bond_indices_range(const Range &r){
typedef boost::transform_iterator<Get_bond_indices, typename Range::iterator> Tr;
return boost::make_iterator_range(Tr(r.begin(),Get_bond_indices()),
Tr(r.end(), Get_bond_indices()));
return internal::rangelib::transformed(r,Get_bond_indices());
}
@ -166,12 +156,9 @@ struct Is_backbone {
//! Return an iterator range which returns skips non-backbone atoms
template <class Range>
boost::iterator_range<boost::filter_iterator<Is_backbone, typename Range::iterator> >
internal::rangelib::filtered_range<Range, Is_backbone>
make_backbone_range(const Range& r){
return boost::make_iterator_range(boost::make_filter_iterator(Is_backbone(),
r.begin(), r.end()),
boost::make_filter_iterator(Is_backbone(),
r.end(), r.end()));
return internal::rangelib::filtered(r, Is_backbone());
}
//! Return true if an atom is a AC.
@ -185,16 +172,12 @@ struct Is_CA {
//! Return an iterator range which returns skips non-backbone atoms
template <class Range>
boost::iterator_range<boost::filter_iterator<Is_CA, typename Range::iterator> >
make_ca_range(const Range& r){
return boost::make_iterator_range(boost::make_filter_iterator(Is_CA(),
r.begin(),
r.end()),
boost::make_filter_iterator(Is_CA(),
r.end(),
r.end()));
internal::rangelib::filtered_range<Range, Is_CA>
make_backbone_range(const Range& r){
return internal::rangelib::filtered(r, Is_CA());
}
template <class OK_atom>
struct Is_ok_bond {
typedef bool result_type;
@ -226,13 +209,10 @@ struct Is_ok_bond {
};
//! Return an iterator range which returns skips non-backbone atoms
template <class Range, class OKA>
boost::iterator_range<boost::filter_iterator<Is_ok_bond<OKA> , typename Range::iterator> >
make_ok_bond_range( OKA oka, const Range& r){
return boost::make_iterator_range(boost::make_filter_iterator(Is_ok_bond<OKA>(oka),
r.begin(), r.end()),
boost::make_filter_iterator(Is_ok_bond<OKA>(oka),
r.end(), r.end()));
template <class Range, class OKA>
internal::rangelib::filtered_range<Range, Is_ok_bond<OKA> >
make_backbone_range(OKA oka, const Range& r){
return internal::rangelib::filtered(r, Is_ok_bond<OKA>(oka));
}