@@ -241,132 +241,9 @@ template<std::size_t N>
241
241
}
242
242
243
243
244
- template <class TChar , TChar start, TChar end>
245
- constexpr void lexical_range (auto func)
246
- {
247
- return cfg_helpers::do_lexical_range<0 , TChar, start, end>(func);
248
- }
249
-
250
-
251
- /* *
252
- * @brief Check if a char is in range [start, end]
253
- */
254
- template <class TChar >
255
- constexpr bool in_lexical_range (TChar c, TChar start, TChar end)
256
- {
257
- return (start <= c) && (c <= end);
258
- }
259
-
260
- /* *
261
- * @brief Check if a char is in range (start, end)
262
- */
263
- template <class TChar >
264
- constexpr bool in_lexical_range_strict (TChar c, TChar start, TChar end)
265
- {
266
- return (start < c) && (c < end);
267
- }
268
-
269
- /* *
270
- * @brief For a range [start..., c, ...end] lexical_intersect returns ranges [start, c), (c, end]. Does not handle cases when start or end is equal to c
271
- */
272
- template <class TChar >
273
- constexpr auto lexical_intersect (TChar c, TChar start, TChar end)
274
- {
275
- return std::make_pair (std::make_pair (start, static_cast <TChar>(static_cast <std::size_t >(c) - 1 )), std::make_pair (static_cast <TChar>(static_cast <std::size_t >(c) + 1 ), end));
276
- }
277
-
278
- /* *
279
- * @brief For a range [start, end] and c=start OR c=end lexical_intersect_edge returns (start, end] OR [start, end)
280
- */
281
- template <class TChar >
282
- constexpr auto lexical_intersect_edge (TChar c, TChar start, TChar end)
283
- {
284
- if (c == start)
285
- return std::make_pair (static_cast <TChar>(static_cast <std::size_t >(start) + 1 ), end);
286
- return std::make_pair (start, static_cast <TChar>(static_cast <std::size_t >(end) - 1 ));
287
- }
288
-
289
-
290
- /* *
291
- * @brief Check if ranges [start_lhs, end_lhs], [start_rhs, end_rhs] intersect
292
- */
293
- template <class TChar >
294
- constexpr bool in_lexical_range (TChar a_start, TChar a_end, TChar b_start, TChar b_end)
295
- {
296
- // [ ( ] ) or [ ( ) ]
297
- // return (b_start <= a_end && b_end >= a_start) || (a_start <= b_end || a_end >= b_start);
298
- return (a_start > b_start ? a_start : b_start) <= (a_end < b_end ? a_end : b_end);
299
- }
300
-
301
-
302
- /* *
303
- * @brief Enum for lexical_ranges_intersect return type. [ ] - range A, ( ) - range B
304
- */
305
- enum class RangesIntersect
306
- {
307
- Partial, /* * [ ( ] ) */
308
- AInB, /* * ( [ ] ) Note: 1st and 3rd ranges are of the same type (B) */
309
- BInA, /* * [ ( ) ] Note: 1st and 3rd ranges are of the same type (A) */
310
- OnlyA, /* * [( ) ] Note: first range is empty */
311
- OnlyB, /* * ([ ] ) Note: third range is empty */
312
- };
313
-
314
-
315
- /* *
316
- * @brief For ranges [start_lhs, end_lhs] and [start_rhs, end_rhs] lexical_ranges_intersect returns a tuple of 3 ranges: [lhs, intersect, rhs]. Any resulting range may be a singleton (c, c)
317
- */
318
- template <class TChar >
319
- constexpr auto lexical_ranges_intersect (TChar a_start, TChar a_end, TChar b_start, TChar b_end)
320
- {
321
- using range_type = std::pair<TChar, TChar>;
322
-
323
- // Calculate intersection boundaries
324
- const TChar intersect_start = a_start > b_start ? a_start : b_start; // std::max(a_start, b_start)
325
- const TChar intersect_end = a_end < b_end ? a_end : b_end; // std::min(a_end, b_end )
326
- const auto i_decr = static_cast <TChar>(static_cast <std::size_t >(intersect_start) - 1 );
327
- const auto i_incr = static_cast <TChar>(static_cast <std::size_t >(intersect_end) + 1 );
328
-
329
- const range_type intersect = range_type (intersect_start, intersect_end);
330
-
331
-
332
- // [ ( ) ] or [( ) ] (any combination)
333
- if ((intersect_start == a_start && intersect_end == a_end) || (intersect_start == b_start && intersect_end == b_end))
334
- {
335
- if (a_start == b_start)
336
- return (a_end < b_end ?
337
- // ([ ] )
338
- std::make_pair (RangesIntersect::OnlyB, std::make_tuple (range_type (), intersect, range_type (i_incr, b_end))) :
339
- // [( ) ]
340
- std::make_pair (RangesIntersect::OnlyA, std::make_tuple (range_type (a_start, i_decr), intersect, range_type ())));
341
- else if (a_end == b_end)
342
- return (b_start < a_start ?
343
- // ([ ] )
344
- std::make_pair (RangesIntersect::OnlyB, std::make_tuple (range_type (), intersect, range_type (i_incr, b_end))) :
345
- // [ ( )]
346
- std::make_pair (RangesIntersect::OnlyA, std::make_tuple (range_type (a_start, i_decr), intersect, range_type ())));
347
- else {
348
- // [ ( ) ]
349
- // Note: 1st and 3rd ranges are of the same type
350
- return (a_start == intersect_start ?
351
- // ( [ ] )
352
- std::make_pair (RangesIntersect::AInB, std::make_tuple (range_type (b_start, i_decr), intersect, range_type (i_incr, b_end))) :
353
- // [ ( ) ]
354
- std::make_pair (RangesIntersect::BInA, std::make_tuple (range_type (a_start, i_decr), intersect, range_type (i_incr, a_end))));
355
- }
356
- }
357
-
358
- return (a_start < intersect_start ?
359
- // [ ( ] )
360
- std::make_pair (RangesIntersect::Partial, std::make_tuple (range_type (a_start, i_decr), intersect, range_type (i_incr, b_end))) :
361
- // ( [ ) ]
362
- std::make_pair (RangesIntersect::Partial, std::make_tuple (range_type (i_incr, a_end), intersect, range_type (b_start, i_decr))));
363
- }
364
-
365
-
366
244
/* *
367
245
* @brief Map enum to its index in increasing order
368
246
* @tparam Max Maximum (last) value of enum
369
- * @tparam TArg List of enum arguments of the same type
370
247
*/
371
248
template <class T , T Max>
372
249
class EnumMap
@@ -422,8 +299,11 @@ class ConstVec
422
299
// Lazy init
423
300
constexpr ConstVec () : _st(), _n(0 ), _cap(0 ) {}
424
301
302
+ // Empty init
303
+ constexpr ConstVec (std::size_t size, std::size_t cap) : _st(new T[cap]), _n(size), _cap(cap) {}
304
+
425
305
// Copy ctor
426
- constexpr ConstVec (const ConstVec<T>& rhs) : _st(new T[rhs.size()]), _n(rhs.size()), _cap(rhs.size()) { deepcopy (rhs); }
306
+ constexpr ConstVec (const ConstVec<T>& rhs) : _st(new T[rhs.size()]), _cap(rhs.size()) { deepcopy (rhs); }
427
307
428
308
// Initialize a singleton
429
309
constexpr explicit ConstVec (const T& elem) : _st(new T[1 ]), _n(1 ), _cap(1 ) { _st[0 ] = elem; }
@@ -470,7 +350,13 @@ class ConstVec
470
350
_st.reset (new T[rhs.size ()]);
471
351
deepcopy (rhs);
472
352
_cap = rhs.size ();
473
- _n = rhs.size ();
353
+ }
354
+
355
+ void init (std::size_t size, std::size_t cap)
356
+ {
357
+ _st.reset (new T[cap]);
358
+ _cap = cap;
359
+ _n = size;
474
360
}
475
361
476
362
[[nodiscard]] std::size_t size () const noexcept { return _n; }
@@ -481,6 +367,16 @@ class ConstVec
481
367
482
368
constexpr const T& operator [](std::size_t i) const { return _st[i]; }
483
369
370
+ /* *
371
+ * @brief Copy rhs.size() elements from rhs and set array size to rhs.size(). Buffer must be allocated beforehand
372
+ */
373
+ void deepcopy (const ConstVec<T>& rhs)
374
+ {
375
+ // Perform a deepcopy of the rhs array up to rhs.size elements
376
+ _n = rhs.size ();
377
+ std::copy_n (rhs._st .get (), rhs.size (), _st.get ());
378
+ }
379
+
484
380
/* *
485
381
* @brief Replace array with a single element
486
382
* @param elem
@@ -505,6 +401,13 @@ class ConstVec
505
401
return *this ;
506
402
}
507
403
404
+ ConstVec<T>& operator +=(const T& rhs)
405
+ {
406
+ _st[_n] = rhs;
407
+ _n++;
408
+ return *this ;
409
+ }
410
+
508
411
friend std::ostream& operator <<(std::ostream& os, const ConstVec<T>& lhs)
509
412
{
510
413
for (std::size_t i = 0 ; i < lhs.size (); i++)
@@ -519,12 +422,6 @@ class ConstVec
519
422
// return std::make_unique<T>(T(std::get<N>(src))...);
520
423
return new T[std::tuple_size_v<std::decay_t <SrcTuple>>]{ T (std::get<N>(src))... };
521
424
}
522
-
523
- void deepcopy (const ConstVec<T>& rhs)
524
- {
525
- // Perform a deepcopy of the rhs array up to rhs.size elements
526
- std::copy_n (rhs._st .get (), rhs.size (), _st.get ());
527
- }
528
425
};
529
426
530
427
0 commit comments