Skip to content

Commit 8de71af

Browse files
committed
Make range checks require random-access iterators, and prepare for *enum metafunctions
1 parent 2c64707 commit 8de71af

File tree

1 file changed

+35
-2
lines changed

1 file changed

+35
-2
lines changed

include/cpp2util.h

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@
213213
#include <cstdio>
214214
#include <cstdint>
215215
#include <algorithm>
216+
#include <compare>
217+
#include <iterator>
216218

217219
#ifndef CPP2_NO_EXCEPTIONS
218220
#include <exception>
@@ -392,15 +394,15 @@ auto assert_not_null(auto&& p CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> declty
392394
//
393395
auto assert_in_bounds(auto&& x, auto&& arg CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> decltype(auto)
394396
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; })
396398
{
397399
Bounds.expects(0 <= arg && arg < std::ssize(x), "out of bounds access attempt detected" CPP2_SOURCE_LOCATION_ARG);
398400
return CPP2_FORWARD(x) [ CPP2_FORWARD(arg) ];
399401
}
400402

401403
auto assert_in_bounds(auto&& x, auto&& arg CPP2_SOURCE_LOCATION_PARAM_WITH_DEFAULT) -> decltype(auto)
402404
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; }))
404406
{
405407
return CPP2_FORWARD(x) [ CPP2_FORWARD(arg) ];
406408
}
@@ -1526,6 +1528,37 @@ template<typename T>
15261528
using alien_memory = T volatile;
15271529

15281530

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+
15291562
//-----------------------------------------------------------------------
15301563
//
15311564
// Speculative: RAII wrapping for the C standard library

0 commit comments

Comments
 (0)