• R/O
  • SSH
  • HTTPS

eirrepo: Commit


Commit MetaInfo

Revision454 (tree)
Time2022-02-24 22:59:51
Authorquiret

Log Message

- added single-value support to UniqueIterate.h facilities + unit tests

Change Summary

Incremental Difference

--- common/sdk/UniqueIterate.h (revision 453)
+++ common/sdk/UniqueIterate.h (revision 454)
@@ -26,18 +26,13 @@
2626 namespace eir
2727 {
2828
29-template <typename>
30-struct is_unique_container : std::false_type
31-{};
32-template <typename... setArgs>
33-struct is_unique_container <Set <setArgs...>> : std::true_type
34-{};
35-template <typename... mvsArgs>
36-struct is_unique_container <MultiValueStore <mvsArgs...>> : std::true_type
37-{};
29+template <typename containerType>
30+concept is_unique_container =
31+ is_multivaluestore <containerType>::value || is_set <containerType>::value;
3832
3933 template <typename itemType, typename containerType, typename callbackType, typename begIterType, typename endIterType>
40-AINLINE std::invoke_result_t <callbackType, itemType> _unique_iterate_single( begIterType& iter, endIterType& enditer, const containerType& container, callbackType&& cb )
34+ requires ( std::is_invocable <callbackType, itemType&&>::value )
35+AINLINE std::invoke_result_t <callbackType, itemType> _unique_iterate_single( begIterType& iter, endIterType& enditer, containerType&& container, callbackType&& cb )
4136 {
4237 while ( iter != enditer )
4338 {
@@ -45,7 +40,7 @@
4540
4641 bool has_prev_instance = false;
4742
48- if constexpr ( is_unique_container <containerType>::value == false )
43+ if constexpr ( is_unique_container <containerType> == false )
4944 {
5045 for ( auto begiter = std::begin( container ); begiter != iter; ++begiter )
5146 {
@@ -85,12 +80,19 @@
8580
8681 // Iterates over a single container, returning each unique value inside exactly once.
8782 template <typename itemType, typename containerType, typename callbackType>
88-inline std::invoke_result_t <callbackType, itemType> unique_iterate_single( const containerType& container, callbackType&& cb )
83+inline std::invoke_result_t <callbackType, itemType> unique_iterate_single( containerType&& container, callbackType&& cb )
8984 {
90- auto iter = std::begin( container );
91- auto enditer = std::end( container );
85+ if constexpr ( std::convertible_to <containerType, itemType> )
86+ {
87+ cb( std::forward <containerType> ( container ) );
88+ }
89+ else
90+ {
91+ auto iter = std::begin( container );
92+ auto enditer = std::end( container );
9293
93- return _unique_iterate_single <itemType> ( iter, enditer, container, std::forward <callbackType> ( cb ) );
94+ return _unique_iterate_single <itemType> ( iter, enditer, std::forward <containerType> ( container ), std::forward <callbackType> ( cb ) );
95+ }
9496 }
9597
9698 // Helper.
@@ -135,6 +137,10 @@
135137 {
136138 return ( container.Find( item ) );
137139 }
140+ else if constexpr ( EqualityComparableValues <containerType, itemType> )
141+ {
142+ return ( container == item );
143+ }
138144 else
139145 {
140146 for ( const itemType& ai : container )
@@ -208,46 +214,67 @@
208214
209215 auto iterate_container = [&]( const auto& container ) LAINLINE -> bool
210216 {
211- optional_struct_space <decltype(std::begin( container ))> _from_iter;
212- optional_struct_space_init <decltype(std::begin( container ))> _from_iter_init;
213- auto enditer = std::end( container );
214-
215- if ( has_found_prev_yet == false )
217+ if constexpr ( std::same_as <decltype(container), const itemType&> )
216218 {
217- auto fiter = _begin_from <itemType> ( container, _fetch_from_optional <itemType> ( prev ) );
218- if ( !( fiter != enditer ) )
219+ if ( has_found_prev_yet == true )
219220 {
220- goto next;
221+ if ( does_contain_to( container_idx, container ) == false )
222+ {
223+ fres = container;
224+ return true;
225+ }
221226 }
222- ++fiter;
223- _from_iter_init = { _from_iter, std::move( fiter ) };
224- has_found_prev_yet = true;
227+ else
228+ {
229+ if ( container == _fetch_from_optional <itemType> ( prev ) )
230+ {
231+ has_found_prev_yet = true;
232+ }
233+ }
225234 }
226235 else
227236 {
228- _from_iter_init = { _from_iter, std::begin( container ) };
229- }
237+ optional_struct_space <decltype(std::begin( container ))> _from_iter;
238+ optional_struct_space_init <decltype(std::begin( container ))> _from_iter_init;
239+ auto enditer = std::end( container );
230240
231- {
232- optionalStore res = _unique_iterate_single <itemType> ( _from_iter.get(), enditer, container,
233- [&]( itemType&& item ) LAINLINE -> optionalStore
241+ if ( has_found_prev_yet == false )
242+ {
243+ auto fiter = _begin_from <itemType> ( container, _fetch_from_optional <itemType> ( prev ) );
244+ if ( !( fiter != enditer ) )
234245 {
235- if ( does_contain_to( container_idx, item ) == false )
246+ goto next;
247+ }
248+ ++fiter;
249+ _from_iter_init = { _from_iter, std::move( fiter ) };
250+ has_found_prev_yet = true;
251+ }
252+ else
253+ {
254+ _from_iter_init = { _from_iter, std::begin( container ) };
255+ }
256+
257+ {
258+ optionalStore res = _unique_iterate_single <itemType> ( _from_iter.get(), enditer, container,
259+ [&]( itemType&& item ) LAINLINE -> optionalStore
236260 {
237- return std::move( item );
261+ if ( does_contain_to( container_idx, item ) == false )
262+ {
263+ return std::move( item );
264+ }
265+ return optionalStore();
238266 }
239- return optionalStore();
267+ );
268+
269+ if ( bool(res) )
270+ {
271+ fres = std::move( res );
272+ return true;
240273 }
241- );
242-
243- if ( bool(res) )
244- {
245- fres = std::move( res );
246- return true;
247274 }
275+ next:;
248276 }
249277
250- next:
251278 container_idx++;
252279 return false;
253280 };
@@ -311,13 +338,13 @@
311338 return ( containerContains( container, item ) );
312339 };
313340
314- return std::apply( [&]( const containerTypes&... args ) LAINLINE { return ( _container_find( args ) || ... ); }, std::move( containers ) );
341+ return std::apply( [&]( const containerTypes&... args ) LAINLINE { return ( _container_find( args ) || ... ); }, containers );
315342 };
316343
317344 auto iterate_container = [&]( const auto& container ) LAINLINE
318345 {
319346 unique_iterate_single <itemType> ( container,
320- [&]( itemType&& item ) LAINLINE
347+ [&]( const itemType& item ) LAINLINE
321348 {
322349 if ( does_contain_to( container_idx, item ) == false )
323350 {
@@ -329,7 +356,7 @@
329356 container_idx++;
330357 };
331358
332- std::apply( [&] ( containerTypes&&... args ) LAINLINE { ( iterate_container( args ), ... ); }, std::move( containers ) );
359+ std::apply( [&] ( const containerTypes&... args ) LAINLINE { ( iterate_container( args ), ... ); }, containers );
333360 }
334361
335362 template <typename itemType, typename callbackType, typename... containerTypes>
@@ -372,6 +399,16 @@
372399 {
373400 container.ReplaceValues( oldval, newval );
374401 }
402+ else if constexpr (
403+ std::is_reference <decltype(container)>::value &&
404+ std::convertible_to <putItemType, typename std::remove_reference <decltype(container)>::type>
405+ )
406+ {
407+ if ( container == oldval )
408+ {
409+ container = newval;
410+ }
411+ }
375412 else
376413 {
377414 for ( auto& ival : container )
@@ -388,7 +425,7 @@
388425 }
389426
390427 template <typename itemType, typename... containerTypes>
391- requires ( sizeof...( containerTypes ) > 0 && ( std::is_const <containerTypes>::value || ... ) == false )
428+ requires ( sizeof...( containerTypes ) > 0 && std::is_const <itemType>::value == false && ( std::is_const <containerTypes>::value || ... ) == false )
392429 AINLINE void removeFromContainer( const itemType& findval, containerTypes&&... containers )
393430 {
394431 auto _remove_lambda = [&]( auto& container ) LAINLINE
@@ -405,6 +442,13 @@
405442 {
406443 container.RemoveByValue( findval );
407444 }
445+ else if constexpr ( std::same_as <decltype(container), itemType&> )
446+ {
447+ if ( findval != itemType() && container == findval )
448+ {
449+ container = itemType();
450+ }
451+ }
408452 else
409453 {
410454 if ( findval != itemType() )
--- unittests/src/uniqueiter.cpp (revision 453)
+++ unittests/src/uniqueiter.cpp (revision 454)
@@ -110,6 +110,19 @@
110110 }
111111 printf( "ok.\n" );
112112
113+ printf( "testing uniqueFetchNextPtr (with single pointers)..." );
114+ {
115+ int a, b, c, d, e;
116+
117+ assert( eir::uniqueFetchNextPtr <int*> ( nullptr, &a, &b, &c, &c, &d, &e ) == &a );
118+ assert( eir::uniqueFetchNextPtr <int*> ( &a, &a, &b, &c, &c, &d, &e ) == &b );
119+ assert( eir::uniqueFetchNextPtr <int*> ( &b, &a, &b, &c, &c, &d, &e ) == &c );
120+ assert( eir::uniqueFetchNextPtr <int*> ( &c, &a, &b, &c, &c, &d, &e ) == &d );
121+ assert( eir::uniqueFetchNextPtr <int*> ( &d, &a, &b, &c, &c, &d, &e ) == &e );
122+ assert( eir::uniqueFetchNextPtr <int*> ( &e, &a, &b, &c, &c, &d, &e ) == nullptr );
123+ }
124+ printf( "ok.\n" );
125+
113126 printf( "testing uniqueIterate (single container)..." );
114127 {
115128 size_t cnt = 0;
@@ -164,6 +177,21 @@
164177 }
165178 printf( "ok.\n" );
166179
180+ printf( "testing uniqueIterate (with single values)..." );
181+ {
182+ size_t cnt = 0;
183+
184+ eir::uniqueIterate <int> (
185+ [&] ( int& i )
186+ {
187+ cnt++;
188+ }, 1, 1, 2, 3, 4, 5, 5, 6
189+ );
190+
191+ assert( cnt == 6 );
192+ }
193+ printf( "ok.\n" );
194+
167195 printf( "testing isInContainer..." );
168196 {
169197 assert( eir::isInContainer( 1, std::array{ 0, 1, 2 } ) == true );
@@ -171,6 +199,8 @@
171199 assert( eir::isInContainer( 5, eir::Set <int, CRTHeapAllocator> ( std::array{ 1, 3, 5 } ) ) == true );
172200 assert( eir::isInContainer( 4, eir::Vector <int, CRTHeapAllocator> ( std::array{ 2, 6, 0 } ) ) == false );
173201 assert( eir::isInContainer( 42, std::array{ 1, 2, 3 }, std::array{ 5, 9, 12 }, eir::Vector <int, CRTHeapAllocator> ( std::array{ 31, 42, 53 } ) ) == true );
202+ assert( eir::isInContainer( 99, 11, 22, 33, 44, 55, 66, 77, 88, 99 ) == true );
203+ assert( eir::isInContainer( 1, 0, -42, 88 ) == false );
174204 }
175205 printf( "ok.\n" );
176206
@@ -241,6 +271,20 @@
241271 }
242272 printf( "ok.\n" );
243273
274+ printf( "testing replaceInContainer (with references)..." );
275+ {
276+ int a = 1;
277+ int b = 2;
278+ int c = 1;
279+
280+ eir::replaceInContainer( 1, 9, a, b, c );
281+
282+ assert( a == 9 );
283+ assert( b == 2 );
284+ assert( c == 9 );
285+ }
286+ printf( "ok.\n" );
287+
244288 printf( "testing removeFromContainer (with array)..." );
245289 {
246290 auto arr = std::array{ 1, 2, 3 };
@@ -291,4 +335,18 @@
291335 assert( mvs.Find( 99 ) == false );
292336 }
293337 printf( "ok.\n" );
338+
339+ printf( "testing removeFromContainer (with references)..." );
340+ {
341+ int a = 1;
342+ int b = 2;
343+ int c = 1;
344+
345+ eir::removeFromContainer( 1, a, b, c );
346+
347+ assert( a == 0 );
348+ assert( b == 2 );
349+ assert( c == 0 );
350+ }
351+ printf( "ok.\n" );
294352 }
\ No newline at end of file
Show on old repository browser