31
31
32
32
// These are declared at global scope purely so that error messages
33
33
// are smaller and easier to understand.
34
- enum class CallType { kConstRef , kConstMove };
34
+ enum class CallType { kMutableRef , kConstRef , kMutableMove , kConstMove };
35
35
36
36
template <int >
37
37
struct Empty {
38
+ constexpr CallType value () & { return CallType::kMutableRef ; }
38
39
constexpr CallType value () const & { return CallType::kConstRef ; }
40
+ constexpr CallType value () && { return CallType::kMutableMove ; }
39
41
constexpr CallType value () const && { return CallType::kConstMove ; }
40
42
};
41
43
44
+ // Unconditionally return an lvalue reference to `t`.
45
+ template <typename T>
46
+ constexpr T& AsLValue (T&& t) {
47
+ return t;
48
+ }
49
+
42
50
template <typename T>
43
51
struct NotEmpty {
44
52
T value;
@@ -375,8 +383,24 @@ TEST(CompressedTupleTest, Constexpr) {
375
383
constexpr int value () const { return v; }
376
384
int v;
377
385
};
378
- constexpr CompressedTuple<int , double , CompressedTuple<int >, Empty<0 >> x (
379
- 7 , 1.25 , CompressedTuple<int >(5 ), {});
386
+
387
+ using Tuple = CompressedTuple<int , double , CompressedTuple<int >, Empty<0 >>;
388
+
389
+ constexpr int r0 =
390
+ AsLValue (Tuple (1 , 0.75 , CompressedTuple<int >(9 ), {})).get <0 >();
391
+ constexpr double r1 =
392
+ AsLValue (Tuple (1 , 0.75 , CompressedTuple<int >(9 ), {})).get <1 >();
393
+ constexpr int r2 =
394
+ AsLValue (Tuple (1 , 0.75 , CompressedTuple<int >(9 ), {})).get <2 >().get <0 >();
395
+ constexpr CallType r3 =
396
+ AsLValue (Tuple (1 , 0.75 , CompressedTuple<int >(9 ), {})).get <3 >().value ();
397
+
398
+ EXPECT_EQ (r0, 1 );
399
+ EXPECT_EQ (r1, 0.75 );
400
+ EXPECT_EQ (r2, 9 );
401
+ EXPECT_EQ (r3, CallType::kMutableRef );
402
+
403
+ constexpr Tuple x (7 , 1.25 , CompressedTuple<int >(5 ), {});
380
404
constexpr int x0 = x.get <0 >();
381
405
constexpr double x1 = x.get <1 >();
382
406
constexpr int x2 = x.get <2 >().get <0 >();
@@ -387,6 +411,18 @@ TEST(CompressedTupleTest, Constexpr) {
387
411
EXPECT_EQ (x2, 5 );
388
412
EXPECT_EQ (x3, CallType::kConstRef );
389
413
414
+ constexpr int m0 = Tuple (5 , 0.25 , CompressedTuple<int >(3 ), {}).get <0 >();
415
+ constexpr double m1 = Tuple (5 , 0.25 , CompressedTuple<int >(3 ), {}).get <1 >();
416
+ constexpr int m2 =
417
+ Tuple (5 , 0.25 , CompressedTuple<int >(3 ), {}).get <2 >().get <0 >();
418
+ constexpr CallType m3 =
419
+ Tuple (5 , 0.25 , CompressedTuple<int >(3 ), {}).get <3 >().value ();
420
+
421
+ EXPECT_EQ (m0, 5 );
422
+ EXPECT_EQ (m1, 0.25 );
423
+ EXPECT_EQ (m2, 3 );
424
+ EXPECT_EQ (m3, CallType::kMutableMove );
425
+
390
426
constexpr CompressedTuple<Empty<0 >, TrivialStruct, int > trivial = {};
391
427
constexpr CallType trivial0 = trivial.get <0 >().value ();
392
428
constexpr int trivial1 = trivial.get <1 >().value ();
0 commit comments