Skip to content

Commit 5b6a79e

Browse files
authored
Add a flag NO_SCALAR_REFERENCE_USED_IN_PATTERNS to control behavior. (#85)
* scalarPtr * typo * single header Co-authored-by: Bowen Fu <missing>
1 parent f1a6af4 commit 5b6a79e

8 files changed

Lines changed: 75 additions & 16 deletions

File tree

develop/matchit/patterns.h

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include <type_traits>
1010
#include <variant>
1111

12+
#if !defined(NO_SCALAR_REFERENCES_USED_IN_PATTERNS)
13+
#define NO_SCALAR_REFERENCES_USED_IN_PATTERNS 0
14+
#endif // !defined(NO_SCALAR_REFERENCES_USED_IN_PATTERNS)
15+
1216
namespace matchit
1317
{
1418
namespace impl
@@ -569,8 +573,11 @@ namespace matchit
569573
// support constexpr.
570574
template <typename Value>
571575
using AppResultCurTuple =
572-
std::conditional_t<std::is_lvalue_reference_v<AppResult<Value>> ||
573-
std::is_scalar_v<AppResult<Value>>,
576+
std::conditional_t<std::is_lvalue_reference_v<AppResult<Value>>
577+
#if NO_SCALAR_REFERENCES_USED_IN_PATTERNS
578+
|| std::is_scalar_v<AppResult<Value>>
579+
#endif // NO_SCALAR_REFERENCES_USED_IN_PATTERNS
580+
,
574581
std::tuple<>,
575582
std::tuple<std::decay_t<AppResult<Value>>>>;
576583

@@ -1537,16 +1544,16 @@ namespace matchit
15371544
std::tuple<>>);
15381545
constexpr auto x = [](auto &&t)
15391546
{ return t; };
1540-
static_assert(std::is_same_v<PatternTraits<App<decltype(x), Wildcard>>::
1541-
template AppResultTuple<int32_t>,
1542-
std::tuple<>>);
1547+
// static_assert(std::is_same_v<PatternTraits<App<decltype(x), Wildcard>>::
1548+
// template AppResultTuple<int32_t>,
1549+
// std::tuple<>>);
15431550
static_assert(
15441551
std::is_same_v<PatternTraits<App<decltype(x), Wildcard>>::
15451552
template AppResultTuple<std::array<int32_t, 3>>,
15461553
std::tuple<std::array<int32_t, 3>>>);
1547-
static_assert(std::is_same_v<PatternTraits<And<App<decltype(x), Wildcard>>>::
1548-
template AppResultTuple<int32_t>,
1549-
std::tuple<>>);
1554+
// static_assert(std::is_same_v<PatternTraits<And<App<decltype(x), Wildcard>>>::
1555+
// template AppResultTuple<int32_t>,
1556+
// std::tuple<>>);
15501557

15511558
static_assert(PatternTraits<And<App<decltype(x), Wildcard>>>::nbIdV == 0);
15521559
static_assert(PatternTraits<And<App<decltype(x), Id<int32_t>>>>::nbIdV == 1);

develop/matchit/utility.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,21 @@ namespace matchit
9292
{
9393
return dynamic_cast<T*>(std::addressof(b));
9494
}
95+
96+
constexpr auto operator()(T const& b) const
97+
{
98+
return std::addressof(b);
99+
}
100+
101+
constexpr auto operator()(T& b) const
102+
{
103+
return std::addressof(b);
104+
}
95105
};
96106

107+
static_assert(std::is_invocable_v<AsPointer<int>, int>);
108+
static_assert(std::is_invocable_v<AsPointer<std::tuple<int>>, std::tuple<int>>);
109+
97110
template <typename T>
98111
constexpr AsPointer<T> asPointer;
99112

include/matchit.h

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ namespace matchit
316316
#include <type_traits>
317317
#include <variant>
318318

319+
#if !defined(NO_SCALAR_REFERENCES_USED_IN_PATTERNS)
320+
#define NO_SCALAR_REFERENCES_USED_IN_PATTERNS 0
321+
#endif // !defined(NO_SCALAR_REFERENCES_USED_IN_PATTERNS)
322+
319323
namespace matchit
320324
{
321325
namespace impl
@@ -876,8 +880,11 @@ namespace matchit
876880
// support constexpr.
877881
template <typename Value>
878882
using AppResultCurTuple =
879-
std::conditional_t<std::is_lvalue_reference_v<AppResult<Value>> ||
880-
std::is_scalar_v<AppResult<Value>>,
883+
std::conditional_t<std::is_lvalue_reference_v<AppResult<Value>>
884+
#if NO_SCALAR_REFERENCES_USED_IN_PATTERNS
885+
|| std::is_scalar_v<AppResult<Value>>
886+
#endif // NO_SCALAR_REFERENCES_USED_IN_PATTERNS
887+
,
881888
std::tuple<>,
882889
std::tuple<std::decay_t<AppResult<Value>>>>;
883890

@@ -1844,16 +1851,16 @@ namespace matchit
18441851
std::tuple<>>);
18451852
constexpr auto x = [](auto &&t)
18461853
{ return t; };
1847-
static_assert(std::is_same_v<PatternTraits<App<decltype(x), Wildcard>>::
1848-
template AppResultTuple<int32_t>,
1849-
std::tuple<>>);
1854+
// static_assert(std::is_same_v<PatternTraits<App<decltype(x), Wildcard>>::
1855+
// template AppResultTuple<int32_t>,
1856+
// std::tuple<>>);
18501857
static_assert(
18511858
std::is_same_v<PatternTraits<App<decltype(x), Wildcard>>::
18521859
template AppResultTuple<std::array<int32_t, 3>>,
18531860
std::tuple<std::array<int32_t, 3>>>);
1854-
static_assert(std::is_same_v<PatternTraits<And<App<decltype(x), Wildcard>>>::
1855-
template AppResultTuple<int32_t>,
1856-
std::tuple<>>);
1861+
// static_assert(std::is_same_v<PatternTraits<And<App<decltype(x), Wildcard>>>::
1862+
// template AppResultTuple<int32_t>,
1863+
// std::tuple<>>);
18571864

18581865
static_assert(PatternTraits<And<App<decltype(x), Wildcard>>>::nbIdV == 0);
18591866
static_assert(PatternTraits<And<App<decltype(x), Id<int32_t>>>>::nbIdV == 1);
@@ -2025,8 +2032,21 @@ namespace matchit
20252032
{
20262033
return dynamic_cast<T*>(std::addressof(b));
20272034
}
2035+
2036+
constexpr auto operator()(T const& b) const
2037+
{
2038+
return std::addressof(b);
2039+
}
2040+
2041+
constexpr auto operator()(T& b) const
2042+
{
2043+
return std::addressof(b);
2044+
}
20282045
};
20292046

2047+
static_assert(std::is_invocable_v<AsPointer<int>, int>);
2048+
static_assert(std::is_invocable_v<AsPointer<std::tuple<int>>, std::tuple<int>>);
2049+
20302050
template <typename T>
20312051
constexpr AsPointer<T> asPointer;
20322052

sample/isLarge.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#define NO_SCALAR_REFERENCES_USED_IN_PATTERNS 1
2+
13
#include "matchit.h"
24
#include <iostream>
35

sample/quotientRemainder.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#define NO_SCALAR_REFERENCES_USED_IN_PATTERNS 1
2+
13
#include "matchit.h"
24
#include <iostream>
35

sample/someNone.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#define NO_SCALAR_REFERENCES_USED_IN_PATTERNS 1
2+
13
#include "matchit.h"
24
#include <iostream>
35
#include <optional>

sample/variantAny.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#define NO_SCALAR_REFERENCES_USED_IN_PATTERNS 1
2+
13
#include "matchit.h"
24
#include <iostream>
35

test/matchit/app.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,14 @@ TEST(App, someAs)
3131
auto const x = std::unique_ptr<Base>{new Derived};
3232
EXPECT_TRUE(matched(x, some(as<Derived>(_))));
3333
}
34+
35+
TEST(App, scalarPtr)
36+
{
37+
auto const x = std::make_unique<int>(10);
38+
Id<int*> xPtr;
39+
match(x)
40+
(
41+
pattern | some(as<int>(asPtr<int>(xPtr))) = [&] { *(*xPtr) = 20 ; }
42+
);
43+
EXPECT_EQ(*x, 20);
44+
}

0 commit comments

Comments
 (0)