mirror of https://github.com/CGAL/cgal
use rangelib to simplify things, probably should remove extra gunk from rangelib at some point
This commit is contained in:
parent
9409f1f68c
commit
9f2f9be17a
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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 );
|
||||
}
|
||||
*/
|
||||
|
|
@ -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
|
||||
|
||||
*/
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue