All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
SmartRanges.h
Go to the documentation of this file.
1 #ifndef GAUDIKERNEL_SMARTRANGES_H
2 #define GAUDIKERNEL_SMARTRANGES_H 1
3 // ============================================================================
4 // STD&STL
5 // ============================================================================
6 #include <cassert>
7 #include <limits>
8 // ============================================================================
9 // Gaudikernel
10 // ============================================================================
11 // #include "GaudiKernel/Range.h"
12 #include "Range.h"
13 // ============================================================================
14 // boost
15 // ============================================================================
16 #include "boost/iterator/iterator_facade.hpp"
17 #include "boost/iterator/filter_iterator.hpp"
18 #include "boost/iterator/transform_iterator.hpp"
19 // ============================================================================
31 // ============================================================================
32 namespace Gaudi
33 {
34  // ==========================================================================
35  namespace details
36  {
37  // ========================================================================
44  template <class ITERATOR, class MASK>
46  : public boost::iterator_facade<masked_iterator<ITERATOR,MASK>,
47  typename std::iterator_traits<ITERATOR>::value_type,
48  boost::forward_traversal_tag,
49  typename std::iterator_traits<ITERATOR>::reference,
50  typename std::iterator_traits<ITERATOR>::difference_type>
51  {
52  public:
53  // ========================================================================
54  // masked_iterator() = default ;
55  masked_iterator ( const MASK& mask , ITERATOR b )
56  : m_iterator ( b )
57  , m_mask ( mask )
58  , m_index ( mask.find_first() )
59  {
60  if ( MASK::npos != m_index ) { std::advance ( m_iterator , m_index ) ; }
61  }
62  // ========================================================================
63  masked_iterator ( MASK&& mask , ITERATOR b )
64  : m_iterator ( b )
65  , m_mask ( mask )
66  , m_index ( mask.find_first() )
67  {
68  if ( MASK::npos != m_index ) { std::advance ( m_iterator , m_index ) ; }
69  }
70  // ========================================================================
72  : m_iterator ()
73  , m_mask ()
74  , m_index ( MASK::npos )
75  {}
76  // ========================================================================
77  private:
78  // ========================================================================
80  void increment()
81  {
82  const size_t m = m_mask.find_next( m_index ) ;
83  if ( m != MASK::npos ) { std::advance ( m_iterator , m - m_index ) ; }
84  m_index = m ;
85  }
86  // ========================================================================
88  dereference () const { return *m_iterator ; }
89  // ========================================================================
90  bool equal( const masked_iterator& other ) const
91  { return m_index == other.m_index ; }
92  // ========================================================================
93  private:
94  // ========================================================================
95  ITERATOR m_iterator ;
96  MASK m_mask ;
97  size_t m_index ;
98  // ========================================================================
99  };
100  // ==========================================================================
107  template <class ITERATOR, class INDICES>
109  public boost::iterator_facade<index_iterator<ITERATOR,INDICES>,
110  typename std::iterator_traits<ITERATOR>::value_type,
111  boost::forward_traversal_tag,
112  typename std::iterator_traits<ITERATOR>::reference,
113  typename std::iterator_traits<ITERATOR>::difference_type>
114  {
115  public:
116  // ========================================================================
117  index_iterator ( const INDICES& indices , ITERATOR b , ITERATOR e )
118  : m_begin ( b )
119  , m_size ( std::distance ( b , e ) )
120  , m_indices ( indices )
121  , m_index ( 0 )
122  {}
123  // ========================================================================
124  index_iterator ( INDICES&& indices , ITERATOR b , ITERATOR e )
125  : m_begin ( b )
126  , m_size ( std::distance ( b , e ) )
127  , m_indices ( indices )
128  , m_index ( 0 )
129  {}
130  // ========================================================================
132  : m_begin ( )
133  , m_size ( 0 )
134  , m_indices ( )
135  , m_index ( 0 )
136  {}
137  // ========================================================================
138  private:
139  // ========================================================================
140  friend class boost::iterator_core_access ;
141  void increment()
142  {
143  if ( m_index < m_indices.size() )
144  {
145  // 1. advance
146  ++m_index ;
147  // 2. advance further, if out of range
148  if ( m_size <= m_indices[m_index] ) { increment () ; }
149  }
150  }
152  {
153  ITERATOR it = m_begin ;
154  if ( m_index < m_indices.size() )
155  { it = std::next ( m_begin , m_indices[ m_index ] ) ; }
156  return *it;
157  }
158  // ========================================================================
159  bool equal( const index_iterator& other ) const
160  {
161  if ( m_index == other.m_index && m_indices.size() == other.m_indices.size() ) { return true ; }
162  return // special stuff to catch "end"
163  ( m_index == m_indices.size() ) &&
164  ( other.m_index == other.m_indices.size() ) ;
165  }
166  // ========================================================================
167  private:
168  // ========================================================================
169  ITERATOR m_begin ;
171  INDICES m_indices ;
173  // ======================================================================
174  };
175  // =======================================================================
176  } // end of namespace Gaudi::details
177  // =========================================================================
205  template <class PREDICATE,class CONTAINER>
206  inline
209  make_filter_range ( PREDICATE p , const CONTAINER& c )
210  {
212  return { ITER( p , c.begin() ) , ITER ( p , c.end () ) } ;
213  }
214  // ==========================================================================
243  template <class FUNCTOR,class CONTAINER>
244  inline
247  make_transform_range ( FUNCTOR f , const CONTAINER& c )
248  {
250  return { ITER ( c.begin() , f ) , ITER ( c.end () , f ) } ;
251  }
252  // ==========================================================================
278  template<class MASK, class CONTAINER>
279  inline
280  Gaudi::Range_<typename Gaudi::details::container<CONTAINER>::Container,
282  make_mask_range ( MASK m , const CONTAINER& c )
283  {
284  typedef Gaudi::details::masked_iterator<typename Gaudi::details::container<CONTAINER>::Iterator,MASK> ITER ;
285  if ( m.size() > c.size() ) { m.resize( c.size() ) ; }
286  return { ITER ( std::move(m) , c.begin() ) , ITER () } ;
287  }
288  // ============================================================================
316  template<class INDICES, class CONTAINER>
317  inline
318  Gaudi::Range_<typename Gaudi::details::container<CONTAINER>::Container,
320  make_index_range ( INDICES m , const CONTAINER& c )
321  {
322  static_assert( std::is_convertible<typename INDICES::value_type,std::size_t>::value ,"index type is not convertible") ;
323  static_assert( std::numeric_limits<typename INDICES::value_type>::is_specialized ,"index type is not specialized") ;
324  static_assert( !std::numeric_limits<typename INDICES::value_type>::is_signed ,"index type must be unsigned" ) ;
325  typedef Gaudi::details::index_iterator<typename Gaudi::details::container<CONTAINER>::Iterator,INDICES> ITER ;
326  return { ITER ( std::move(m) , c.begin() , c.end() ) , ITER () } ;
327  }
328  // =========================================================================
329 }
330 // ============================================================================
331 // The END
332 // ============================================================================
333 #endif // GAUDIKERNEL_SMARTRANGES_H
334 // ============================================================================
index_iterator(const INDICES &indices, ITERATOR b, ITERATOR e)
Definition: SmartRanges.h:117
T advance(T...args)
STL namespace.
Gaudi::Range_< typename Gaudi::details::container< CONTAINER >::Container, Gaudi::details::masked_iterator< typename Gaudi::details::container< CONTAINER >::Iterator, MASK > > make_mask_range(MASK m, const CONTAINER &c)
create "masking" range with mask
Definition: SmartRanges.h:282
masked_iterator(const MASK &mask, ITERATOR b)
Definition: SmartRanges.h:55
bool equal(const masked_iterator &other) const
Definition: SmartRanges.h:90
std::iterator_traits< ITERATOR >::reference dereference() const
Definition: SmartRanges.h:151
"index" iterator iterates ober "indiced" intries in the cotainer/range
Definition: SmartRanges.h:108
T next(T...args)
constexpr double m
Definition: SystemOfUnits.h:93
bool equal(const index_iterator &other) const
Definition: SmartRanges.h:159
"masked" iterator iterates ober "masked" intries in the cotainner/range
Definition: SmartRanges.h:45
This file has been imported from LoKi project "C++ ToolKit for Smart and Friendly Physics Analysis" ...
T move(T...args)
index_iterator(INDICES &&indices, ITERATOR b, ITERATOR e)
Definition: SmartRanges.h:124
boost::spirit::classic::position_iterator2< ForwardIterator > Iterator
Definition: Iterator.h:18
masked_iterator(MASK &&mask, ITERATOR b)
Definition: SmartRanges.h:63
Gaudi::Range_< typename Gaudi::details::container< CONTAINER >::Container, boost::transform_iterator< FUNCTOR, typename Gaudi::details::container< CONTAINER >::Iterator > > make_transform_range(FUNCTOR f, const CONTAINER &c)
create "transform" range with functors
Definition: SmartRanges.h:247
Useful class for representation of "sequence" of the objects through the range of valid iterators...
Definition: Range.h:102
std::iterator_traits< ITERATOR >::reference dereference() const
Definition: SmartRanges.h:88
Gaudi::Range_< typename Gaudi::details::container< CONTAINER >::Container, Gaudi::details::index_iterator< typename Gaudi::details::container< CONTAINER >::Iterator, INDICES > > make_index_range(INDICES m, const CONTAINER &c)
create "index" range with indices
Definition: SmartRanges.h:320
friend class boost::iterator_core_access
Definition: SmartRanges.h:79
Gaudi::Range_< typename Gaudi::details::container< CONTAINER >::Container, boost::filter_iterator< PREDICATE, typename Gaudi::details::container< CONTAINER >::Iterator > > make_filter_range(PREDICATE p, const CONTAINER &c)
create a filtering range with predicate
Definition: SmartRanges.h:209
Helper functions to set/get the application return code.
Definition: __init__.py:1