10 #ifndef SC_GENERIC_HPP 11 #define SC_GENERIC_HPP 19 #include <type_traits> 46 inline std::enable_if_t<is_iterable_enum<T>::value, T&> operator--( T& s )
48 return s =
static_cast<T
>(
static_cast<std::underlying_type_t<T>
>(s) - 1 );
52 inline std::enable_if_t<is_iterable_enum<T>::value, T> operator--( T& s,
int )
60 inline std::enable_if_t<is_iterable_enum<T>::value, T&> operator++( T& s )
62 return s =
static_cast<T
>(
static_cast<std::underlying_type_t<T>
>(s) + 1 );
66 inline std::enable_if_t<is_iterable_enum<T>::value, T> operator++( T& s,
int )
109 template <
typename T>
110 void operator()( T* t )
const 112 using force_T_to_be_complete =
int[
sizeof( T ) ? 1 : -1 ];
113 (void)
sizeof( force_T_to_be_complete );
120 template <
typename I,
typename D>
121 void dispose( I first, I last, D disposer )
123 while ( first != last )
124 disposer( *first++ );
127 template <
typename I>
128 inline void dispose( I first, I last )
140 template <
typename R>
141 auto operator()( R&& r )
const {
143 return begin( std::forward<R>( r ) );
145 template <
typename T>
146 auto operator()(
const std::pair<T, T>& p )
const {
152 template <
typename R>
153 auto operator()( R&& r )
const {
155 return end( std::forward<R>( r ) );
157 template <
typename T>
158 auto operator()(
const std::pair<T, T>& p )
const {
165 template <
typename T>
171 template <
typename T>
172 auto cbegin(
const T& t )
174 return range::begin( t );
177 template <
typename T>
183 template <
typename T>
184 auto cend(
const T& t )
186 return range::end( t );
189 template <
typename R>
190 using iterator_t = decltype(range::begin(std::declval<R&>()));
192 template <
typename R>
193 using value_type_t =
typename std::iterator_traits<iterator_t<R>>::value_type;
195 template <
typename R>
196 using reference_type_t =
typename std::iterator_traits<iterator_t<R>>::reference;
201 template <
typename T>
202 constexpr T&& operator()(T&&
value)
const noexcept {
203 return std::forward<T>(
value);
205 using is_transparent = std::true_type;
210 template <
typename Range,
typename Out>
211 inline Out copy(
const Range& r, Out o )
213 return std::copy( range::begin( r ), range::end( r ), o );
216 template <
typename Range,
typename Out,
typename UnaryPredicate>
217 inline Out copy_if(
const Range& r, Out o, UnaryPredicate pred )
219 return std::copy_if( range::begin( r ), range::end( r ), o, pred );
222 template <
typename Range,
typename D>
223 inline Range& dispose( Range& r, D disposer )
225 dispose( range::begin( r ), range::end( r ), disposer );
229 template <
typename Range>
230 inline Range& dispose( Range& r )
235 template <
typename Range>
236 inline Range& fill( Range& r, value_type_t<Range>
const& t )
238 std::fill( range::begin( r ), range::end( r ), t );
242 template <
typename Range,
typename T,
typename Proj =
identity,
243 typename U = decltype( std::declval<T&&>() + std::declval<std::invoke_result_t<Proj, reference_type_t<Range>>>() )>
244 auto accumulate( Range&& r, T init, Proj proj = {} ) -> U
246 auto first = range::begin( r );
247 auto last = range::end( r );
249 U accum = std::move( init );
250 for ( ; first != last; ++first )
251 accum = std::move( accum ) + std::invoke( proj, *first );
255 #if defined( SC_GCC ) 257 template <
typename T,
size_t N>
258 inline T ( &fill( T ( &r )[ N ],
const T& t ) )[ N ]
260 for (
size_t i = 0; i < N; ++i )
268 template <
typename Range,
typename T,
269 typename Enable = decltype( std::declval<reference_type_t<Range>>() == std::declval<const T&>() )>
270 inline iterator_t<Range> find( Range& r, T
const& t )
272 return std::find( range::begin( r ), range::end( r ), t );
275 template <
typename Range,
typename T,
typename Proj,
276 typename Enable = decltype( std::declval<std::invoke_result_t<Proj, reference_type_t<Range>>>() == std::declval<const T&>() )>
277 inline iterator_t<Range> find( Range& r, T
const&
value, Proj proj )
279 const auto pred = [&value, &proj](
auto&& v ) {
280 return std::invoke( proj, std::forward<decltype(v)>( v ) ) == value;
282 return std::find_if( range::begin( r ), range::end( r ), pred );
285 template <
typename Range,
typename UnaryPredicate>
286 inline iterator_t<Range> find_if( Range& r, UnaryPredicate p )
288 return std::find_if( range::begin( r ), range::end( r ), p );
291 template <
typename Range,
typename UnaryPredicate>
292 inline bool any_of( Range&& r, UnaryPredicate p )
294 return std::any_of( range::begin( r ), range::end( r ), p );
302 template <
typename Range,
typename Value,
typename Proj =
identity>
303 inline bool contains( Range&& r,
const Value& v, Proj proj = Proj{} )
305 return range::find( r, v, proj ) != range::end( r );
308 template <
typename Range,
typename F>
309 inline F for_each( Range&& r, F f )
311 std::for_each( range::begin( r ), range::end( r ),
312 [ &f ](
auto&& v ) { std::invoke( f, std::forward<decltype(v)>( v ) ); } );
316 template <
typename Range,
typename Out,
typename Predicate>
317 inline Out remove_copy_if( Range& r, Out o, Predicate p )
319 return std::remove_copy_if( range::begin( r ), range::end( r ), o, p );
322 template <
typename Range,
typename Out,
typename F>
323 Out transform( Range&& r, Out o, F op )
325 return std::transform( range::begin( r ), range::end( r ), o,
326 [ &op ](
auto&& v ) {
return std::invoke( op, std::forward<decltype(v)>( v ) ); } );
329 template <
typename Range,
typename Range2,
typename Out,
typename F>
330 Out transform( Range&& r, Range2&& r2, Out o, F op_ )
332 const auto op = [ &op_ ] (
auto&& l,
auto&& r ) {
333 return std::invoke( op_, std::forward<decltype(l)>( l ), std::forward<decltype(r)>( r ) );
335 return std::transform( range::begin( r ), range::end( r ), range::begin( r2 ), o, op );
338 template <
typename Range,
typename F>
339 inline iterator_t<Range> transform_self( Range& r, F f )
341 return std::transform( range::begin( r ), range::end( r ), range::begin( r ),
345 template <
typename Range1,
typename Range2,
typename Out>
346 inline Out set_difference(
const Range1& left,
const Range2& right, Out o )
348 return std::set_difference( range::begin( left ), range::end( left ),
349 range::begin( right ), range::end( right ), o );
352 template <
typename Range1,
typename Range2,
typename Out,
typename Compare>
353 inline Out set_difference(
const Range1& left,
const Range2& right, Out o,
356 return std::set_difference( range::begin( left ), range::end( left ),
357 range::begin( right ), range::end( right ), o,
361 template <
typename Range1,
typename Range2,
typename Out>
362 inline Out set_intersection(
const Range1& left,
const Range2& right, Out o )
364 return std::set_intersection( range::begin( left ), range::end( left ),
365 range::begin( right ), range::end( right ), o );
368 template <
typename Range1,
typename Range2,
typename Out,
typename Compare>
369 inline Out set_intersection(
const Range1& left,
const Range2& right, Out o,
372 return std::set_intersection( range::begin( left ), range::end( left ),
373 range::begin( right ), range::end( right ), o,
377 template <
typename Range1,
typename Range2,
typename Out>
378 inline Out set_union(
const Range1& left,
const Range2& right, Out o )
380 return std::set_union( range::begin( left ), range::end( left ),
381 range::begin( right ), range::end( right ), o );
384 template <
typename Range1,
typename Range2,
typename Out,
typename Compare>
385 inline Out set_union(
const Range1& left,
const Range2& right, Out o,
388 return std::set_union( range::begin( left ), range::end( left ),
389 range::begin( right ), range::end( right ), o, c );
392 template <
typename Range>
393 inline Range& sort( Range& r )
395 std::sort( range::begin( r ), range::end( r ) );
399 template <
typename Range,
typename Comp>
400 inline Range& sort( Range& r, Comp c )
402 std::sort( range::begin( r ), range::end( r ), c );
406 template <
typename Range>
407 inline iterator_t<Range> unique( Range& r )
409 return std::unique( range::begin( r ), range::end( r ) );
412 template <
typename Range,
typename Comp>
413 inline iterator_t<Range> unique( Range& r, Comp c )
415 return std::unique( range::begin( r ), range::end( r ), c );
418 template <
typename Range>
419 inline iterator_t<Range> max_element( Range& r )
421 return std::max_element( range::begin( r ), range::end( r ) );
424 template <
typename Range>
425 inline iterator_t<Range> min_element( Range& r )
427 return std::min_element( range::begin( r ), range::end( r ) );
430 template <
typename Range1,
typename Range2>
431 inline void append( Range1& destination, Range2&& source )
433 destination.insert( destination.end(), source.begin(), source.end() );
436 template <
typename Range,
typename Predicate>
437 inline auto count_if( Range&& r, Predicate p ) ->
typename std::iterator_traits<decltype(range::begin( r ))>::difference_type
439 return std::count_if( range::begin( r ), range::end( r ), p );
442 template <
typename Range,
typename T,
typename Compare = std::less<>,
typename Proj =
identity>
443 iterator_t<Range> lower_bound( Range& r,
const T& value, Compare comp = Compare{}, Proj proj = Proj{} )
445 const auto pred = [&value, &proj, &comp](
auto&& v ) {
446 return std::invoke( comp, std::invoke( proj, std::forward<decltype(v)>( v ) ), value );
448 return std::partition_point( range::begin( r ), range::end( r ), pred );
451 template <
typename Range,
typename T,
typename Compare = std::less<>,
typename Proj =
identity>
452 iterator_t<Range> upper_bound( Range& r,
const T& value, Compare comp = Compare{}, Proj proj = Proj{} )
454 const auto pred = [&value, &proj, &comp](
auto&& v ) {
455 return !std::invoke( comp, value, std::invoke( proj, std::forward<decltype(v)>( v ) ) );
457 return std::partition_point( range::begin( r ), range::end( r ), pred );
460 template <
typename Range,
typename T,
typename Compare = std::less<>,
typename Proj =
identity>
461 std::pair<iterator_t<Range>, iterator_t<Range>>
462 equal_range( Range& r,
const T& value, Compare comp = Compare{}, Proj proj = Proj{} )
464 auto b = lower_bound( r, value, comp, proj );
465 if ( b == range::end( r ) )
467 return { b, upper_bound( r, value, comp, proj ) };
470 template <
typename Range,
typename Pred,
typename Proj =
identity>
471 iterator_t<Range> partition( Range& r, Pred pred_, Proj proj = Proj{} )
473 auto pred = [&pred_, &proj](
auto&& v ) ->
bool {
474 return std::invoke( pred_, std::invoke( proj, std::forward<decltype(v)>( v ) ) );
476 return std::partition( range::begin( r ), range::end( r ), pred );
483 template <
typename Container>
489 range::dispose( *
this );
508 template <
typename To,
typename From>
509 inline To debug_cast( From* ptr )
512 return static_cast<To
>( ptr );
514 To result =
dynamic_cast<To
>( ptr );
526 template <
typename To,
typename From>
527 inline To as( From f )
529 To t =
static_cast<To
>( f );
531 static_assert( std::is_arithmetic<To>::value,
"Output type is not arithmetic." );
532 static_assert( std::is_arithmetic<From>::value,
"Input type is not arithmetic." );
534 assert( f == static_cast<From>( t ) );
536 assert( ( From() < f ) == ( To() < t ) );
540 template <
typename T>
541 inline T clamp( T
value, T low, T high )
543 assert( !( high < low ) );
551 template <
typename Sequence>
552 void erase_unordered( Sequence& s,
typename Sequence::iterator pos )
554 assert( !s.empty() && pos != s.end() );
555 typename Sequence::iterator last = s.end();
571 typename std::remove_reference<decltype( *std::declval<T&>() )>::type;
579 template <
typename U>
584 explicit operator bool()
const 586 return static_cast<bool>( _M_t );
589 const element_type* operator->()
const 594 operator const element_type*()
const 599 const element_type& operator*()
const 604 const element_type*
get()
const 609 element_type*& get_ref()
616 element_type* operator->()
621 operator element_type*()
626 element_type& operator*()
636 template <
typename U>
639 this->_M_t = std::forward<U>( u );
647 #endif // SC_GENERIC_HPP Definition: generic.hpp:151
Definition: generic.hpp:484
Definition: generic.hpp:41
Definition: generic.hpp:135
Represents a JSON value. Use Value for UTF8 encoding and default allocator.
Definition: document.h:66
Definition: sc_data.cpp:17
Definition: generic.hpp:567
Definition: generic.hpp:139
Definition: generic.hpp:107
helper class to make a class non-moveable
Definition: generic.hpp:98
helper class to make a class non-copyable
Definition: generic.hpp:81
Definition: generic.hpp:200