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