|
213 | 213 | #include <cstdio>
|
214 | 214 | #include <cstdint>
|
215 | 215 | #include <algorithm>
|
| 216 | + #include <compare> |
| 217 | + #include <iterator> |
216 | 218 |
|
217 | 219 | #ifndef CPP2_NO_EXCEPTIONS
|
218 | 220 | #include <exception>
|
@@ -392,15 +394,15 @@ auto assert_not_null(auto&& p CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> declty
|
392 | 394 | //
|
393 | 395 | auto assert_in_bounds(auto&& x, auto&& arg CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> decltype(auto)
|
394 | 396 | requires (std::is_integral_v<CPP2_TYPEOF(arg)> &&
|
395 |
| - requires { std::ssize(x); x[arg]; }) |
| 397 | + requires { std::ssize(x); x[arg]; std::begin(x) + 2; }) |
396 | 398 | {
|
397 | 399 | Bounds.expects(0 <= arg && arg < std::ssize(x), "out of bounds access attempt detected" CPP2_SOURCE_LOCATION_ARG);
|
398 | 400 | return CPP2_FORWARD(x) [ CPP2_FORWARD(arg) ];
|
399 | 401 | }
|
400 | 402 |
|
401 | 403 | auto assert_in_bounds(auto&& x, auto&& arg CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> decltype(auto)
|
402 | 404 | requires (!(std::is_integral_v<CPP2_TYPEOF(arg)> &&
|
403 |
| - requires { std::ssize(x); x[arg]; })) |
| 405 | + requires { std::ssize(x); x[arg]; std::begin(x) + 2; })) |
404 | 406 | {
|
405 | 407 | return CPP2_FORWARD(x) [ CPP2_FORWARD(arg) ];
|
406 | 408 | }
|
@@ -1526,6 +1528,37 @@ template<typename T>
|
1526 | 1528 | using alien_memory = T volatile;
|
1527 | 1529 |
|
1528 | 1530 |
|
| 1531 | +//----------------------------------------------------------------------- |
| 1532 | +// |
| 1533 | +// strict_value: a strong typedef-like helper for value types |
| 1534 | +// |
| 1535 | +// Intended for use as an underlying type for types/variables where you |
| 1536 | +// don't want implicit conversions or comparisons to happen between |
| 1537 | +// values even if they may share the same underlying type (e.g., |
| 1538 | +// Color::Red and CardGame::Poker may both be represented as an `int` |
| 1539 | +// but shouldn't be interconvertible or intercomparable) |
| 1540 | +// |
| 1541 | +// Used by the `enum` and `flag_enum` metafunctions |
| 1542 | +// |
| 1543 | +//----------------------------------------------------------------------- |
| 1544 | +// |
| 1545 | +template <typename T, typename Tag> |
| 1546 | +class strict_value { |
| 1547 | + T t; |
| 1548 | +public: |
| 1549 | + template <typename U> requires std::is_same_v<T,U> |
| 1550 | + explicit constexpr strict_value(U const& u) : t{u} { } |
| 1551 | + |
| 1552 | + template <typename U> requires std::is_same_v<T,U> |
| 1553 | + explicit constexpr operator U() const { return t; } |
| 1554 | + |
| 1555 | + template <typename U> requires std::is_same_v<T,U> |
| 1556 | + explicit constexpr operator U() { return t; } |
| 1557 | + |
| 1558 | + auto operator<=>( strict_value const& ) const -> std::strong_ordering = default; |
| 1559 | +}; |
| 1560 | + |
| 1561 | + |
1529 | 1562 | //-----------------------------------------------------------------------
|
1530 | 1563 | //
|
1531 | 1564 | // Speculative: RAII wrapping for the C standard library
|
|
0 commit comments