Skip to content

Commit d63deee

Browse files
committed
[views] Take a reference in single_view to ensure proper semantics
1 parent f89a3ad commit d63deee

File tree

7 files changed

+22
-19
lines changed

7 files changed

+22
-19
lines changed

example/view/view.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,9 @@ int main() {
3333
// The work is done here, when accessing the elements of the view.
3434
BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(mammals).name == "Garfield");
3535
BOOST_HANA_RUNTIME_CHECK(hana::at_c<1>(mammals).name == "Snoopy");
36+
37+
// Views have reference semantics, so we can use them to modify the
38+
// original containers (unless the view applies a transformation).
39+
hana::at_c<1>(mammals).name = "Beethoven";
40+
BOOST_HANA_RUNTIME_CHECK(hana::at_c<2>(animals).name == "Beethoven");
3641
}

include/boost/hana/view.hpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,13 @@ BOOST_HANA_NAMESPACE_BEGIN
150150
//////////////////////////////////////////////////////////////////////
151151
template <typename T>
152152
struct single_view_t {
153-
T value_;
153+
T& value_;
154154
using hana_tag = view_tag;
155155
};
156156

157157
template <typename T>
158-
constexpr single_view_t<typename hana::detail::decay<T>::type>
159-
single_view(T&& t)
160-
{ return {static_cast<T&&>(t)}; }
158+
constexpr single_view_t<T> single_view(T& t)
159+
{ return {t}; }
161160

162161
template <typename T>
163162
struct is_view<single_view_t<T>> {
@@ -349,14 +348,7 @@ BOOST_HANA_NAMESPACE_BEGIN
349348

350349
// single_view
351350
template <typename T, typename N>
352-
static constexpr T& apply(detail::single_view_t<T>& view, N const&) {
353-
static_assert(N::value == 0,
354-
"trying to fetch an out-of-bounds element in a hana::single_view");
355-
return view.value_;
356-
}
357-
358-
template <typename T, typename N>
359-
static constexpr T const& apply(detail::single_view_t<T> const& view, N const&) {
351+
static constexpr decltype(auto) apply(detail::single_view_t<T> view, N const&) {
360352
static_assert(N::value == 0,
361353
"trying to fetch an out-of-bounds element in a hana::single_view");
362354
return view.value_;

test/view/single/at.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ using hana::test::ct_eq;
1515

1616
int main() {
1717
{
18-
auto single = hana::detail::single_view(ct_eq<0>{});
18+
ct_eq<0> x{};
19+
auto single = hana::detail::single_view(x);
1920
BOOST_HANA_CONSTANT_CHECK(hana::equal(
2021
hana::at(single, hana::size_c<0>),
21-
ct_eq<0>{}
22+
x
2223
));
2324
}
2425
}

test/view/single/is_empty.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ template <int> struct undefined { };
1313

1414
int main() {
1515
{
16-
auto single = hana::detail::single_view(undefined<0>{});
16+
undefined<0> x{};
17+
auto single = hana::detail::single_view(x);
1718
BOOST_HANA_CONSTANT_CHECK(hana::not_(hana::is_empty(single)));
1819
}
1920
}

test/view/single/length.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ template <int> struct undefined { };
1414

1515
int main() {
1616
{
17-
auto single = hana::detail::single_view(undefined<0>{});
17+
undefined<0> x{};
18+
auto single = hana::detail::single_view(x);
1819
BOOST_HANA_CONSTANT_CHECK(hana::equal(
1920
hana::length(single),
2021
hana::size_c<1>

test/view/single/modifications.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@ namespace hana = boost::hana;
99

1010

1111
int main() {
12-
auto view = hana::detail::single_view(3);
12+
int x = 3;
13+
auto view = hana::detail::single_view(x);
1314
hana::at_c<0>(view) = 93;
1415

1516
BOOST_HANA_RUNTIME_CHECK(hana::at_c<0>(view) == 93);
17+
BOOST_HANA_RUNTIME_CHECK(x == 93);
1618
}

test/view/single/unpack.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ int main() {
1616
auto f = hana::test::_injection<0>{};
1717

1818
{
19-
auto single = hana::detail::single_view(ct_eq<0>{});
19+
ct_eq<0> x{};
20+
auto single = hana::detail::single_view(x);
2021
BOOST_HANA_CONSTANT_CHECK(hana::equal(
2122
hana::unpack(single, f),
22-
f(ct_eq<0>{})
23+
f(x)
2324
));
2425
}
2526
}

0 commit comments

Comments
 (0)