Skip to content

Commit

Permalink
[tutorial] Document that some containers can hold references
Browse files Browse the repository at this point in the history
  • Loading branch information
ldionne committed Sep 13, 2015
1 parent 5e1280e commit 73d71ba
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 17 deletions.
37 changes: 28 additions & 9 deletions doc/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -1793,21 +1793,40 @@ and so on.

@subsection tutorial-containers-elements Container elements

In Hana, containers own their elements. When a container is created, it makes
a _copy_ of the elements used to initialize it and stores them inside the
container. Of course, unnecessary copies are avoided by using move semantics.
Because of those owning semantics, the lifetime of the objects inside the
container is the same as that of the container.
In Hana, containers own their elements. When a container is created, it
normally makes a _copy_ of the elements used to initialize it and stores them
inside the container. Of course, unnecessary copies are avoided by using move
semantics. Because of those owning semantics, the lifetime of the objects
inside the container is the same as that of the container.

@snippet example/tutorial/containers.cpp lifetime

Much like containers in the standard library, containers in Hana expect their
elements to be objects. For this reason, references _may not_ be stored in
them. When references must be stored inside a container, one should use a
`std::reference_wrapper` instead:
However, some containers allow storing references instead of actual objects.
In that case, the owning semantics explained above do not hold anymore. For
example, it is possible to create a `hana::tuple` holding references as
follows:

@snippet example/tutorial/containers.cpp reference_tuple

@note
Of course, a single tuple can also hold some elements by value and other
elements by reference.

Since explicitly specifying the type of the container to achieve by-reference
semantics can be cumbersome (and sometimes downright impossible when that
type is implementation-defined), the `make_xxx` family of functions also
support the use of `reference_wrapper`s:

@snippet example/tutorial/containers.cpp reference_wrapper

When passed to a `hana::make_xxx` function, `std::reference_wrapper`s and
`boost::reference_wrapper`s will cause the container to hold a reference
instead of a `reference_wrapper`. Of course, only the `make_xxx` functions
associated to containers that support holding references implement this
special behavior. To know whether a container is able to hold references
(and implements this behavior), one should consult the reference documentation
for that container.




Expand Down
28 changes: 20 additions & 8 deletions example/tutorial/containers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,29 @@ std::string& s = xs[0_c];

}{

//! [reference_tuple]
std::string hello = "Hello";
std::vector<char> world = {'W', 'o', 'r', 'l', 'd'};

hana::tuple<std::string&, std::vector<char>&> xs{hello, world};

// s is a reference to `hello`
std::string& s = xs[0_c];
BOOST_HANA_RUNTIME_CHECK(&s == &hello);
//! [reference_tuple]

}{

//! [reference_wrapper]
std::vector<int> ints = { /* huge vector of ints */ };
std::vector<std::string> strings = { /* huge vector of strings */ };
std::string hello = "Hello";
std::vector<char> world = {'W', 'o', 'r', 'l', 'd'};

auto map = hana::make_map(
hana::make_pair(hana::type_c<int>, std::ref(ints)),
hana::make_pair(hana::type_c<std::string>, std::ref(strings))
);
auto xs = hana::make_tuple(std::ref(hello), std::ref(world));

auto& v = map[hana::type_c<int>].get();
BOOST_HANA_RUNTIME_CHECK(&v == &ints);
std::string& hello_ref = xs[0_c];
std::vector<char>& world_ref = xs[1_c];
BOOST_HANA_RUNTIME_CHECK(&hello_ref == &hello);
BOOST_HANA_RUNTIME_CHECK(&world_ref == &world);
//! [reference_wrapper]

}
Expand Down

0 comments on commit 73d71ba

Please sign in to comment.