Skip to content

Commit 57d659d

Browse files
authored
Merge pull request #3 from TartanLlama/reference
Support optional references
2 parents e589ae4 + 883df6b commit 57d659d

File tree

8 files changed

+2508
-1411
lines changed

8 files changed

+2508
-1411
lines changed

README.md

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# optional
2-
Single header implementation of `std::optional` with functional-style extensions.
2+
Single header implementation of `std::optional` with functional-style extensions and support for references.
33

44
Clang + GCC: [![Linux Build Status](https://travis-ci.org/TartanLlama/optional.png?branch=master)](https://travis-ci.org/TartanLlama/optional)
55
MSVC: [![Windows Build Status](https://ci.appveyor.com/api/projects/status/k5x00xa11y3s5wsg?svg=true)](https://ci.appveyor.com/project/TartanLlama/optional)
@@ -66,6 +66,26 @@ The interface is the same as `std::optional`, but the following member functions
6666
- `take`: returns the current value, leaving the optional empty.
6767
* `opt_string.take().map(&std::string::size); //opt_string now empty;`
6868

69+
In addition to those member functions, optional references are also supported:
70+
71+
```
72+
int i = 42;
73+
tl::optional<int&> o = i;
74+
*o == 42; //true
75+
i = 12;
76+
*o = 12; //true
77+
&*o == &i; //true
78+
```
79+
80+
Assignment has rebind semantics rather than assign-through semantics:
81+
82+
```
83+
int j = 8;
84+
o = j;
85+
86+
&*o == &j; //true
87+
```
88+
6989
### Compiler support
7090

7191
Tested on:

docs/index.md

Lines changed: 405 additions & 30 deletions
Large diffs are not rendered by default.

standardese.config

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[output]
2+
format=commonmark
3+
link_extension=html

tests/assignment.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include "catch.hpp"
22
#include "optional.hpp"
33

4-
TEST_CASE("Assignment", "[assignment]") {
4+
TEST_CASE("Assignment value", "[assignment.value]") {
55
tl::optional<int> o1 = 42;
66
tl::optional<int> o2 = 12;
77
tl::optional<int> o3;
@@ -32,3 +32,40 @@ TEST_CASE("Assignment", "[assignment]") {
3232
o1 = std::move(o4);
3333
REQUIRE(*o1 == 42);
3434
}
35+
36+
37+
TEST_CASE("Assignment reference", "[assignment.ref]") {
38+
auto i = 42;
39+
auto j = 12;
40+
41+
tl::optional<int&> o1 = i;
42+
tl::optional<int&> o2 = j;
43+
tl::optional<int&> o3;
44+
45+
o1 = o1;
46+
REQUIRE(*o1 == 42);
47+
REQUIRE(&*o1 == &i);
48+
49+
o1 = o2;
50+
REQUIRE(*o1 == 12);
51+
52+
o1 = o3;
53+
REQUIRE(!o1);
54+
55+
auto k = 42;
56+
o1 = k;
57+
REQUIRE(*o1 == 42);
58+
REQUIRE(*o1 == i);
59+
REQUIRE(*o1 == k);
60+
REQUIRE(&*o1 != &i);
61+
REQUIRE(&*o1 == &k);
62+
63+
k = 12;
64+
REQUIRE(*o1 == 12);
65+
66+
o1 = tl::nullopt;
67+
REQUIRE(!o1);
68+
69+
o1 = std::move(o2);
70+
REQUIRE(*o1 == 12);
71+
}

tests/constructors.cpp

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,49 @@
22
#include "optional.hpp"
33

44
TEST_CASE("Constructors", "[constructors]") {
5-
tl::optional<int> o1;
6-
REQUIRE(!o1);
5+
tl::optional<int> o1;
6+
REQUIRE(!o1);
77

8-
tl::optional<int> o2 = tl::nullopt;
9-
REQUIRE(!o2);
8+
tl::optional<int> o2 = tl::nullopt;
9+
REQUIRE(!o2);
1010

11-
tl::optional<int> o3 = 42;
12-
REQUIRE(*o3 == 42);
11+
tl::optional<int> o3 = 42;
12+
REQUIRE(*o3 == 42);
1313

14-
tl::optional<int> o4 = o3;
15-
REQUIRE(*o4 == 42);
14+
tl::optional<int> o4 = o3;
15+
REQUIRE(*o4 == 42);
1616

17-
tl::optional<int> o5 = o1;
18-
REQUIRE(!o5);
17+
tl::optional<int> o5 = o1;
18+
REQUIRE(!o5);
1919

20-
tl::optional<int> o6 = std::move(o3);
21-
REQUIRE(*o6 == 42);
20+
tl::optional<int> o6 = std::move(o3);
21+
REQUIRE(*o6 == 42);
2222

23-
tl::optional<short> o7 = 42;
24-
REQUIRE(*o7 == 42);
23+
tl::optional<short> o7 = 42;
24+
REQUIRE(*o7 == 42);
2525

26-
tl::optional<int> o8 = o7;
27-
REQUIRE(*o8 == 42);
26+
tl::optional<int> o8 = o7;
27+
REQUIRE(*o8 == 42);
2828

29-
tl::optional<int> o9 = std::move(o7);
30-
REQUIRE(*o9 == 42);
29+
tl::optional<int> o9 = std::move(o7);
30+
REQUIRE(*o9 == 42);
31+
32+
{
33+
tl::optional<int &> o;
34+
REQUIRE(!o);
35+
36+
tl::optional<int &> oo = o;
37+
REQUIRE(!oo);
38+
}
39+
40+
{
41+
auto i = 42;
42+
tl::optional<int &> o = i;
43+
REQUIRE(o);
44+
REQUIRE(*o == 42);
45+
46+
tl::optional<int &> oo = o;
47+
REQUIRE(oo);
48+
REQUIRE(*oo == 42);
49+
}
3150
}

tests/extensions.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ TEST_CASE("Monadic operations", "[monadic]") {
122122

123123
// callable which returns a reference
124124
tl::optional<int> o38 = 42;
125-
auto o38r = o38.map([](int& i) -> const int& { return i; });
125+
auto o38r = o38.map([](int &i) -> const int & { return i; });
126126
REQUIRE(o38r);
127127
REQUIRE(*o38r == 42);
128128
}

tests/make_optional.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,10 @@ TEST_CASE("Make optional", "[make_optional]") {
3737
REQUIRE(o5->v[1] == 1);
3838
REQUIRE(std::get<0>(o5->t) == 2);
3939
REQUIRE(std::get<1>(o5->t) == 3);
40+
41+
auto i = 42;
42+
auto o6 = tl::make_optional<int&>(i);
43+
REQUIRE((std::is_same<decltype(o6), tl::optional<int&>>::value));
44+
REQUIRE(o6);
45+
REQUIRE(*o6 == 42);
4046
}

0 commit comments

Comments
 (0)