• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2 / Distributed under the Boost Software License, Version 1.0. (See accompanying
3 / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4 /]
5
6[section Rationale]
7
8[heading There Are Minimal Derived-Type Contraints]
9
10This is the constraint on the `Derived` template parameter to _iter_iface_,
11_view_iface_ and _cont_iface_:
12
13    std::enable_if_t<
14        std::is_class<Derived>::value &&
15        std::is_same<Derived, std::remove_cv_t<Derived>>::value>
16
17This prevents instantiating an interface template with an `int`, a `const`
18type, a reference type, etc.
19
20Further constraints are not possible (for instance, that _view_iface_ is given
21a `Derived` template parameter for a type that has a `begin()` and `end()`),
22because `Derived` is an incomplete type within each *`_interface` template.
23
24[heading Using a Special Access-Granting `struct`]
25
26The interface templates rely mostly on public members provided by their
27`Derived` template parameter.  However, _iter_iface_ requires you to supply
28`base_reference()` functions if you want it to act like an adaptor.  Since at
29least the non-`const` overload provides a non-`const` lvalue reference to one
30of your types data members, it will break the encapsulation of many types to
31leave `base_reference()` a public member.  To allow users to keep these
32overloads private, _access_ exists.
33
34[heading _iter_iface_ Can Act Like an Adaptor, And the Other Interface Templates Can't]
35
36There wouldn't be much point in adding this functionality to _view_iface_,
37because it only uses the `begin()` and `end()` of the `Derived` type anyway.
38
39For _cont_iface_ it also does not make much sense.  Consider how many
40container adaptors you've written.  That's a use case that does not come up
41often.
42
43[heading _iter_iface_ Takes a Lot of Template Parameters, And the Other Interface Templates Don't]
44
45_iter_iface_ does in fact take a lot of template parameters.  However, it
46usually only takes three: the `Derived` type, the iterator category, and the
47iterator's `value_type`.
48
49When you make a proxy iterator, you typically use the _proxy_iter_iface_
50alias, and you again only need the same three template parameters.  Though you
51can opt into more template parameters, the rest are seldom necessary.
52
53By contrast, the _view_iface_ and _cont_iface_ templates have very few
54template parameters.  For _view_iface_, this is because there are no member
55typedefs in the `view` concept.  For _cont_iface_, it was deemed ridiculous to
56create a template whose purpose is to reduce code size, which takes 14
57template parameters.
58
59[heading _cont_iface_ Does not Deduce Nested Types Like `iterator`]
60
61_cont_iface_ could deduce some of the nested types required for a standard
62sequence container.  For instance, `iterator` can be deduced as
63`decltype(*begin())`.  However, a type `D` derived from _cont_iface_ may need
64to use some of these nested types _emdash_ like `iterator` _emdash_ in its
65interface or implementation.  If this is the case, those nested types are not
66available early enough in the parse to be used in `D`, if they come from
67deductions in _cont_iface_.  This leaves the user in the awkward position of
68defining the same nested type with a different name that can be used within
69`D`.  It seems better to leave these types for the user to define.
70
71[heading _cont_iface_ Does not Support Associative or Unordered Associative Containers]
72
73That's right.  Associative containers have an interface that assumes that they
74are node-based containers.  On modern hardware, node-based containers are not
75very efficient, and I don't want to encourage people to write more of them.
76Unordered associative containers have an interface that precludes open
77addressing.  I don't want to encourage more of that either.
78
79[heading _cont_iface_ Does not Satisfy the Allocator-Aware Container Requirements]
80
81It may not be immediately obvious, but _cont_iface_ simply cannot help with
82the allocator-aware requirements.  All of the allocator-aware requirements but
833 are special members and constructors.  A _CRTP_ base template is unable to
84provide those, based on the language rules.  That leaves the `allocator_type`
85typedef, which the user must provide; member `swap()`, which is already a
86container requirement (the allocator-aware table entry just specifies that
87member `swap()` must be constant-time); and `get_allocator()`, which again is
88something the user must provide.
89
90Most of the difficulty of dealing with allocators has to do with the
91implementation details of their use within your container.  _cont_iface_
92provides missing elements of a sequence container's interface, by calling
93user-provided members of that same interface.  It cannot help you with your
94container's implementation.
95
96[endsect]
97