DataTransferKit - Multiphysics Solution Transfer Services  2.0
DTK_EntityIterator.cpp
1 //---------------------------------------------------------------------------//
2 /*
3  Copyright (c) 2012, Stuart R. Slattery
4  All rights reserved.
5 
6  Redistribution and use in source and binary forms, with or without
7  modification, are permitted provided that the following conditions are
8  met:
9 
10  *: Redistributions of source code must retain the above copyright
11  notice, this list of conditions and the following disclaimer.
12 
13  *: Redistributions in binary form must reproduce the above copyright
14  notice, this list of conditions and the following disclaimer in the
15  documentation and/or other materials provided with the distribution.
16 
17  *: Neither the name of the University of Wisconsin - Madison nor the
18  names of its contributors may be used to endorse or promote products
19  derived from this software without specific prior written permission.
20 
21  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33 //---------------------------------------------------------------------------//
39 //---------------------------------------------------------------------------//
40 
41 #include "DTK_EntityIterator.hpp"
42 #include "DTK_DBC.hpp"
43 
44 namespace DataTransferKit
45 {
46 //---------------------------------------------------------------------------//
47 // Constructor.
49  : b_iterator_impl( nullptr )
50 {
51  // Default predicate always returns true.
52  b_predicate = []( Entity v ) { return true; };
53 }
54 
55 //---------------------------------------------------------------------------//
56 // Copy constructor.
58 {
59  b_iterator_impl.reset();
60  if ( rhs.b_iterator_impl )
61  {
62  b_iterator_impl = std::move( rhs.b_iterator_impl->clone() );
63  b_predicate = b_iterator_impl->b_predicate;
64  }
65  else
66  {
67  b_iterator_impl = std::move( rhs.clone() );
68  b_predicate = rhs.b_predicate;
69  }
70 }
71 
72 //---------------------------------------------------------------------------//
73 // Assignment operator.
75 {
76  b_iterator_impl.reset();
77  if ( this == &rhs )
78  {
79  return *this;
80  }
81  if ( rhs.b_iterator_impl )
82  {
83  b_iterator_impl = std::move( rhs.b_iterator_impl->clone() );
84  b_predicate = b_iterator_impl->b_predicate;
85  }
86  else
87  {
88  b_iterator_impl = std::move( rhs.clone() );
89  b_predicate = rhs.b_predicate;
90  }
91  return *this;
92 }
93 
94 //---------------------------------------------------------------------------//
96 
97 //---------------------------------------------------------------------------//
98 // Pre-increment operator.
99 EntityIterator &EntityIterator::operator++()
100 {
101  DTK_REQUIRE( b_iterator_impl );
102  DTK_REQUIRE( *b_iterator_impl != b_iterator_impl->end() );
103 
104  increment();
105  return *b_iterator_impl;
106 }
107 
108 //---------------------------------------------------------------------------//
109 // Post-increment operator.
110 EntityIterator EntityIterator::operator++( int n )
111 {
112  DTK_REQUIRE( b_iterator_impl );
113  DTK_REQUIRE( *b_iterator_impl != b_iterator_impl->end() );
114 
115  const EntityIterator tmp( *this );
116  increment();
117  return tmp;
118 }
119 
120 //---------------------------------------------------------------------------//
121 // Dereference operator.
122 Entity &EntityIterator::operator*( void )
123 {
124  DTK_REQUIRE( b_iterator_impl );
125  return b_iterator_impl->operator*();
126 }
127 
128 //---------------------------------------------------------------------------//
129 // Dereference operator.
130 Entity *EntityIterator::operator->( void )
131 {
132  DTK_REQUIRE( b_iterator_impl );
133  return b_iterator_impl->operator->();
134 }
135 
136 //---------------------------------------------------------------------------//
137 // Equal comparison operator.
138 bool EntityIterator::operator==( const EntityIterator &rhs ) const
139 {
140  if ( nullptr == b_iterator_impl )
141  return ( nullptr == b_iterator_impl );
142  return b_iterator_impl->operator==( rhs );
143 }
144 
145 //---------------------------------------------------------------------------//
146 // Not equal comparison operator.
147 bool EntityIterator::operator!=( const EntityIterator &rhs ) const
148 {
149  return !( b_iterator_impl->operator==( rhs ) );
150 }
151 
152 //---------------------------------------------------------------------------//
153 // Size of the iterator. This is the number of objects in the iterator that
154 // meet the predicate criteria.
155 std::size_t EntityIterator::size() const
156 {
157  std::size_t size = 0;
158  if ( b_iterator_impl )
159  {
160  size = std::distance( this->begin(), this->end() );
161  }
162  return size;
163 }
164 
165 //---------------------------------------------------------------------------//
166 // An iterator assigned to the beginning.
167 EntityIterator EntityIterator::begin() const
168 {
169  EntityIterator begin_it;
170  if ( b_iterator_impl )
171  {
172  begin_it = b_iterator_impl->begin();
173  begin_it.b_predicate = b_predicate;
174  begin_it.advanceToFirstValidElement();
175  }
176  return begin_it;
177 }
178 
179 //---------------------------------------------------------------------------//
180 // An iterator assigned to the end.
181 EntityIterator EntityIterator::end() const
182 {
183  if ( b_iterator_impl )
184  {
185  return b_iterator_impl->end();
186  }
187  return EntityIterator();
188 }
189 
190 //---------------------------------------------------------------------------//
191 // Create a clone of the iterator.
192 std::unique_ptr<EntityIterator> EntityIterator::clone() const
193 {
194  return std::unique_ptr<EntityIterator>( new EntityIterator() );
195 }
196 
197 //---------------------------------------------------------------------------//
198 // Advance the iterator to the first valid element that satisfies the
199 // predicate or the end of the iterator.
200 void EntityIterator::advanceToFirstValidElement()
201 {
202  DTK_REQUIRE( b_iterator_impl );
203  if ( ( *this != end() ) && !b_predicate( **this ) )
204  {
205  increment();
206  }
207 }
208 
209 //---------------------------------------------------------------------------//
210 // Increment the iterator implementation forward until either a valid
211 // increment is found or we have reached the end.
212 void EntityIterator::increment()
213 {
214  DTK_REQUIRE( b_iterator_impl );
215  DTK_REQUIRE( *b_iterator_impl != b_iterator_impl->end() );
216 
217  // Apply the increment operator.
218  EntityIterator &it = b_iterator_impl->operator++();
219 
220  // Get the end of the range.
221  EntityIterator end = b_iterator_impl->end();
222 
223  // If the we are not at the end or the predicate is not satisfied by the
224  // current element, increment until either of these conditions is
225  // satisfied.
226  while ( it != end && !b_predicate( *it ) )
227  {
228  it = b_iterator_impl->operator++();
229  }
230 }
231 
232 //---------------------------------------------------------------------------//
233 
234 } // end namespace DataTransferKit
235 
236 //---------------------------------------------------------------------------//
237 // end DTK_EntityIterator.cpp
238 //---------------------------------------------------------------------------//
Geometric entity interface definition.
Definition: DTK_Entity.hpp:61
Entity iterator interface.
EntityIterator & operator=(const EntityIterator &rhs)
Assignment operator.
Assertions and Design-by-Contract for error handling.
virtual ~EntityIterator()
Destructor.
DTK_BasicEntitySet.cpp.