Imported Upstream version 1.64.0
[platform/upstream/boost.git] / libs / intrusive / doc / intrusive.qbk
1 [/
2  / Copyright (c) 2006-2013 Ion Gaztanaga
3  /
4  / Distributed under the Boost Software License, Version 1.0. (See accompanying
5  / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  /]
7
8 [library Boost.Intrusive
9     [quickbook 1.6]
10     [authors [Krzikalla, Olaf], [Gaztanaga, Ion]]
11     [copyright 2005 Olaf Krzikalla, 2006-2015 Ion Gaztanaga]
12     [id intrusive]
13     [dirname intrusive]
14     [purpose Intrusive containers]
15     [license
16         Distributed under the Boost Software License, Version 1.0.
17         (See accompanying file LICENSE_1_0.txt or copy at
18         [@http://www.boost.org/LICENSE_1_0.txt])
19     ]
20 ]
21
22 [section:introduction Introduction]
23
24 [section:introduction_presenting Presenting Boost.Intrusive]
25
26 [*Boost.Intrusive] is a library presenting some intrusive containers to
27 the world of C++. Intrusive containers are special containers
28 that offer [link intrusive.performance better performance]
29 and exception safety guarantees than non-intrusive containers (like STL containers).
30
31 The performance benefits of intrusive containers makes them ideal as a building
32 block to efficiently construct complex containers like multi-index containers or
33 to design high performance code like memory allocation algorithms.
34
35 While intrusive containers were and are widely used in C, they
36 became more and more forgotten in C++ due to the presence of the standard
37 containers which don't support intrusive techniques.[*Boost.Intrusive] wants to
38 push intrusive containers usage encapsulating the implementation in
39 STL-like interfaces. Hence anyone familiar with standard containers can easily use
40 [*Boost.Intrusive].
41
42 [endsect]
43
44 [section:introduction_building_intrusive Building Boost.Intrusive]
45
46 There is no need to compile anything to use [*Boost.Intrusive], since it's
47 a header only library. Just include your Boost header directory in your
48 compiler include path.
49
50 [endsect]
51
52 [endsect]
53
54 [section:intrusive_vs_nontrusive Intrusive and non-intrusive containers]
55
56 [section:differences_intrusive_vs_nontrusive Differences between intrusive and non-intrusive containers]
57
58 The main difference between intrusive containers and non-intrusive containers is
59 that in C++ non-intrusive containers store [*copies] of values passed by the user.
60 Containers use the `Allocator` template parameter to allocate the stored values:
61
62 [c++]
63
64    #include <list>
65    #include <assert.h>
66
67    int main()
68    {
69       std::list<MyClass> myclass_list;
70
71       MyClass myclass(...);
72       myclass_list.push_back(myclass);
73
74       //The stored object is different from the original object
75       assert(&myclass != &myclass_list.front());
76       return 0;
77    }
78
79
80 To store the newly allocated copy of `myclass`, the container needs additional
81 data: `std::list` usually allocates nodes that contain pointers to the
82 next and previous node and the value itself. Something similar to:
83
84 [c++]
85
86    //A possible implementation of a std::list<MyClass> node
87    class list_node
88    {
89       list_node *next;
90       list_node *previous;
91       MyClass    value;
92    };
93
94
95 On the other hand, an intrusive container does not store copies of passed objects,
96 but it stores the objects themselves. The additional data needed to insert the object
97 in the container must be provided by the object itself. For example, to insert `MyClass`
98 in an intrusive container that implements a linked list, `MyClass` must contain the
99 needed ['next] and ['previous] pointers:
100
101 [c++]
102
103    class MyClass
104    {
105       MyClass *next;
106       MyClass *previous;
107       //Other members...
108    };
109
110    int main()
111    {
112       acme_intrusive_list<MyClass> list;
113
114       MyClass myclass;
115       list.push_back(myclass);
116
117       //"myclass" object is stored in the list
118       assert(&myclass == &list.front());
119       return 0;
120    }
121
122 As we can see, knowing which additional data the class should contain is not
123 an easy task. [*Boost.Intrusive] offers several intrusive containers and an easy
124 way to make user classes compatible with those containers.
125
126 [endsect]
127
128 [section:properties_of_intrusive Properties of Boost.Intrusive containers]
129
130 Semantically, a [*Boost.Intrusive] container is similar to a STL container
131 holding pointers to objects. That is, if you have an intrusive list holding
132 objects of type `T`, then `std::list<T*>` would allow you to do quite the
133 same operations (maintaining and navigating a set of objects of type T and
134 types derived from it).
135
136 A non-intrusive container has some limitations:
137
138 *  An object can only belong to one container: If you want to share an object
139    between two containers, you either have to store multiple copies of those
140    objects or you need to use containers of pointers: `std::list<Object*>`.
141
142 *  The use of dynamic allocation to create copies of passed values can be a performance
143    and size bottleneck in some applications. Normally, dynamic allocation imposes
144    a size overhead for each allocation to store bookkeeping information and a
145    synchronization to protected concurrent allocation from different threads.
146
147 *  Only copies of objects are stored in non-intrusive containers. Hence copy
148    or move constructors and copy or move assignment operators are required. Non-copyable
149    and non-movable objects can't be stored in non-intrusive containers.
150
151 *  It's not possible to store a derived object in a STL-container while
152    retaining its original type.
153
154 Intrusive containers have some important advantages:
155
156 *  Operating with intrusive containers doesn't invoke any memory management at all.
157    The time and size overhead associated with dynamic memory can be minimized.
158
159 *  Iterating an Intrusive container needs less memory accesses than the semantically
160    equivalent container of pointers: iteration is faster.
161
162 *  Intrusive containers offer better exception guarantees than non-intrusive containers.
163    In some situations intrusive containers offer a no-throw guarantee that can't be
164    achieved with non-intrusive containers.
165
166 *  The computation of an iterator to an element from a pointer or reference to that element
167    is a constant time operation (computing the position of `T*` in a `std::list<T*>` has
168    linear complexity).
169
170 *  Intrusive containers offer predictability when inserting and erasing objects since no
171    memory management is done with intrusive containers. Memory management usually is not a predictable
172    operation so complexity guarantees from non-intrusive containers are looser than the guarantees
173    offered by intrusive containers.
174
175 Intrusive containers have also downsides:
176
177 *  Each type stored in an intrusive container needs additional memory holding the
178    maintenance information needed by the container. Hence, whenever a certain type will
179    be stored in an intrusive container [*you have to change the definition of that type]
180    appropriately. Although this task is easy with [*Boost.Intrusive], touching the
181    definition of a type is sometimes a crucial issue.
182
183 *  In intrusive containers you don't store a copy of an object, [*but rather the original object
184    is linked with other objects in the container]. Objects don't need copy-constructors or assignment
185    operators to be stored in intrusive containers. But you have to take care of possible side effects,
186    whenever you change the contents of an object (this is especially important for
187    associative containers).
188
189 *  The user [*has to manage the lifetime of inserted objects] independently from the
190    containers.
191
192 *  Again you have to be [*careful]: in contrast to STL containers [*it's easy to render an
193    iterator invalid] without touching the intrusive container directly, because the object
194    can be disposed before is erased from the container.
195
196 *  [*Boost.Intrusive] containers are [*non-copyable and non-assignable]. Since intrusive
197    containers don't have allocation capabilities, these operations make no sense. However,
198    swapping can be used to implement move capabilities. To ease the implementation of
199    copy constructors and assignment operators of classes storing [*Boost.Intrusive]
200    containers, [*Boost.Intrusive] offers special cloning functions. See
201    [link intrusive.clone_from Cloning Boost.Intrusive containers] section for more information.
202
203 *  Analyzing the thread safety of a program that uses containers is harder with intrusive containers, because
204    the container might be modified indirectly without an explicit call to a container member.
205
206 [table Summary of intrusive containers advantages and disadvantages
207     [[Issue]                                                                     [Intrusive]                         [Non-intrusive]]
208     [[Memory management]                                                         [External]                          [Internal through allocator]]
209     [[Insertion/Erasure time]                                                    [Faster]                            [Slower]]
210     [[Memory locality]                                                           [Better]                            [Worse]]
211     [[Can hold non-copyable and non-movable objects by value]                    [Yes]                               [No]]
212     [[Exception guarantees]                                                      [Better]                            [Worse]]
213     [[Computation of iterator from value]                                        [Constant]                          [Non-constant]]
214     [[Insertion/erasure predictability]                                          [High]                              [Low]]
215     [[Memory use]                                                                [Minimal]                           [More than minimal]]
216     [[Insert objects by value retaining polymorphic behavior]                    [Yes]                               [No (slicing)]]
217     [[User must modify the definition of the values to insert]                   [Yes]                               [No]]
218     [[Containers are copyable]                                                   [No]                                [Yes]]
219     [[Inserted object's lifetime managed by]                                     [User (more complex)]               [Container (less complex)]]
220     [[Container invariants can be broken without using the container]            [Easier]                            [Harder (only with containers of pointers)]]
221     [[Thread-safety analysis]                                                    [Harder]                            [Easier]]
222 ]
223
224 For a performance comparison between Intrusive and Non-intrusive containers see
225 [link intrusive.performance Performance] section.
226
227 [endsect]
228
229 [endsect]
230
231 [section:usage How to use Boost.Intrusive]
232
233 If you plan to insert a class in an intrusive container, you have to make some decisions
234 influencing the class definition itself. Each class that will be used in an intrusive
235 container needs some appropriate data members storing the information needed by the
236 container. We will take a simple intrusive container, the intrusive list
237 ([classref boost::intrusive::list boost::intrusive::list]), for the following
238 examples, but all [*Boost.Intrusive] containers are very similar. To compile
239 the example using [classref boost::intrusive::list boost::intrusive::list],
240 just include:
241
242 [c++]
243
244    #include <boost/intrusive/list.hpp>
245
246 Every class to be inserted in an intrusive container, needs to contain a hook that
247 will offer the necessary data and resources to be insertable in the container.
248 With [*Boost.Intrusive] you just choose the hook to be a public base class or
249 a public member of the class to be inserted. [*Boost.Intrusive] also offers
250 more flexible hooks for advanced users, as explained in the chapter
251 [link intrusive.function_hooks Using function hooks], but usually base or member
252 hooks are good enough for most users.
253
254 [section:usage_base_hook Using base hooks]
255
256 For [classref boost::intrusive::list list], you can publicly derive from
257 [classref boost::intrusive::list_base_hook list_base_hook].
258
259 [c++]
260
261    template <class ...Options>
262    class list_base_hook;
263
264 The class can take several options. [*Boost.Intrusive] classes receive arguments in the
265 form `option_name<option_value>`. You can specify the following options:
266
267 *  [*`tag<class Tag>`]: this argument serves as a tag, so you can derive from more than one
268    [classref boost::intrusive::list_base_hook list_base_hook] and hence put an object in
269    multiple intrusive lists at the same time. An incomplete type can serve as a tag.
270    If you specify two base hooks, you [*must] specify a different
271    tag for each one. Example: `list_base_hook< tag<tag1> >`. If no tag is specified
272    a default one will be used (more on default tags later).
273
274 *  [*`link_mode<link_mode_type LinkMode>`]: The second template argument controls the
275    linking policy. [*Boost.Intrusive] currently supports
276    3 modes: `normal_link`, `safe_link` and `auto_unlink`. By default, `safe_link`
277    mode is used. More about these in sections
278    [link intrusive.safe_hook Safe hooks] and [link intrusive.auto_unlink_hooks Auto-unlink hooks].
279    Example: `list_base_hook< link_mode<auto_unlink> >`
280
281 *  [*`void_pointer<class VoidPointer>`]: this option is the pointer type to be used
282    internally in the hook. The default value is `void *`, which means that raw pointers
283    will be used in the hook. More about this in the section titled
284    [link intrusive.using_smart_pointers Using smart pointers with Boost.Intrusive containers].
285    Example: `list_base_hook< void_pointer< my_smart_ptr<void> >`
286
287 For the following examples, let's forget the options and use the default values:
288
289 [c++]
290
291    #include <boost/intrusive/list.hpp>
292
293    using namespace boost::intrusive;
294
295    class Foo
296       //Base hook with default tag, raw pointers and safe_link mode
297       :  public list_base_hook<>
298    { /**/ };
299
300 After that, we can define the intrusive list:
301
302 [c++]
303
304    template <class T, class ...Options>
305    class list;
306
307 `list` receives the type to be inserted in the container (`T`) as the first parameter
308 and optionally, the user can specify options. We have 3 option types:
309
310 *  [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
311    [*`value_traits<class ValueTraits>`]: All these options specify the relationship
312    between the type `T` to be inserted in the list and the hook (since we can
313    have several hooks in the same `T` type). `member_hook` will be explained
314    a bit later and `value_traits` will be explained in the
315    [link intrusive.value_traits Containers with custom ValueTraits] section.
316    [*If no option is specified, the container will be configured to use the base
317    hook with the default tag].
318    Some options configured for the hook (the type of the pointers, link mode, etc.)
319    will be propagated to the container.
320
321 *  [*`constant_time_size<bool Enabled>`]: Specifies if a constant time `size()`
322    function is demanded for the container. This will instruct the intrusive
323    container to store an additional member to keep track of the current size of the
324    container. By default, constant-time size is activated.
325
326 *  [*`size_type<class SizeType>`]: Specifies an unsigned type that can hold
327    the size of the container. This type will be the type returned by `list.size()`
328    and the type stored in the intrusive container if `constant_time_size<true>`
329    is requested.
330    The user normally will not need to change this type, but some
331    containers can have a `size_type` that might be different from `std::size_t`
332    (for example, STL-like containers use the `size_type` defined by their allocator).
333    [*Boost.Intrusive] can be used to implement such containers specifying the
334    type of the size. By default the type is `std::size_t`.
335
336 Example of a constant-time size intrusive list that will store Foo objects, using
337 the base hook with the default tag:
338
339 [c++]
340
341    typedef list<Foo> FooList;
342
343 Example of an intrusive list with non constant-time size that will store Foo objects:
344
345 [c++]
346
347    typedef list<Foo, constant_time_size<false> > FooList;
348
349 Remember that the user must specify the base hook in the container declaration
350 if the base hook has no default tag, because that usually means that the type
351 has more than one base hook, and a container shall know which hook will be
352 using:
353
354 [c++]
355
356    #include <boost/intrusive/list.hpp>
357
358    using namespace boost::intrusive;
359
360    struct my_tag1;
361    struct my_tag2;
362
363    typedef list_base_hook< tag<my_tag>  > BaseHook;
364    typedef list_base_hook< tag<my_tag2> > BaseHook2;
365    class Foo   :  public BaseHook, public BaseHook2
366    { /**/ };
367
368    typedef list< Foo, base_hook<BaseHook>  > FooList;
369    typedef list< Foo, base_hook<BaseHook2> > FooList2;
370
371 Once the list is defined, we can use it:
372
373 [c++]
374
375    //An object to be inserted in the list
376    Foo foo_object;
377    FooList list;
378
379    list.push_back(object);
380
381    assert(&list.front() == &foo_object);
382
383 [endsect]
384
385 [section:usage_member_hook Using member hooks]
386
387 Sometimes an 'is-a' relationship between list hooks and the list value types
388 is not desirable. In this case, using a member hook as a data member instead of
389 'disturbing' the hierarchy might be the right way: you can add a public data
390 member `list_member_hook<...>` to your class.
391 This class can be configured with the same options as `list_base_hook`
392 except the option `tag`:
393
394 [c++]
395
396    template <class ...Options>
397    class list_member_hook;
398
399 Example:
400
401 [c++]
402
403    #include <boost/intrusive/list.hpp>
404
405    class Foo
406    {
407       public:
408       list_member_hook<> hook_;
409       //...
410    };
411
412 When member hooks are used, the `member_hook` option is used to configure the
413 list:
414
415 [c++]
416
417    //This option will configure "list" to use the member hook
418    typedef member_hook<Foo, list_member_hook<>, &Foo::hook_> MemberHookOption;
419
420    //This list will use the member hook
421    typedef list<Foo, MemberHookOption> FooList;
422
423 Now we can use the container:
424
425 [c++]
426
427    //An object to be inserted in the list
428    Foo foo_object;
429    FooList list;
430
431    list.push_back(object);
432
433    assert(&list.front() == &foo_object);
434
435 [endsect]
436
437 However, member hooks have some implementation limitations: If there is a virtual inheritance
438 relationship between the parent and the member hook, then the distance between the parent
439 and the hook is not a compile-time fixed value so obtaining the address of
440 the parent from the member hook is not possible without reverse engineering compiler
441 produced RTTI. Apart from this, the non-standard pointer to member implementation for classes
442 with complex inheritance relationships in MSVC ABI compatible-compilers is not supported
443 by member hooks since it also depends on compiler-produced RTTI information.
444
445 [section:usage_both_hooks Using both hooks]
446
447 You can insert the same object in several intrusive containers at the same time,
448 using one hook per container. This is a full example using base and member hooks:
449
450 [import ../example/doc_how_to_use.cpp]
451 [doc_how_to_use_code]
452
453 [endsect]
454
455 [section:usage_lifetime Object lifetime]
456
457 Even if the interface of [classref boost::intrusive::list list] is similar to
458 `std::list`, its usage is a bit different: You always have to keep in mind that
459 you directly store objects in intrusive containers, not copies. The lifetime of a
460 stored object is not bound to or managed by the container:
461
462 *  When the container gets destroyed before the object, the object is not destroyed,
463    so you have to be careful to avoid resource leaks.
464
465 *  When the object is destroyed before the container, your program is likely to crash,
466    because the container contains a pointer to an non-existing object.
467
468 [endsect]
469
470
471 [endsect]
472
473 [section:usage_when When to use?]
474
475 Intrusive containers can be used for highly optimized algorithms, where speed is a crucial
476 issue and:
477
478 *  additional memory management should be avoided.
479 *  the programmer needs to efficiently track the construction and destruction of objects.
480 *  exception safety, especially the no-throw guarantee, is needed.
481 *  the computation of an iterator to an element from a pointer or reference
482    to that element should be a constant time operation.
483 *  it's important to achieve a well-known worst-time system response.
484 *  localization of data (e.g. for cache hit optimization) leads to measurable effects.
485
486 The last point is important if you have a lot of containers over a set of elements. E.g. if
487 you have a vector of objects (say, `std::vector<Object>`), and you also have a list
488 storing a subset of those objects (`std::list<Object*>`), then operating on an Object
489 from the list iterator (`std::list<Object*>::iterator`) requires two steps:
490
491 *  Access from the iterator (usually on the stack) to the list node storing a pointer to `Object`.
492 *  Access from the pointer to `Object` to the Object stored in the vector.
493
494 While the objects themselves are tightly packed in the memory of the vector
495 (a vector's memory is guaranteed to be contiguous), and form something
496 like a data block, list nodes may be dispersed in the heap memory.
497 Hence depending on your system you might get a lot of cache misses. The same doesn't hold
498 for an intrusive list. Indeed, dereferencing an iterator from an intrusive list is performed in
499 the same two steps as described above. But the list node is already embedded in the Object, so
500 the memory is directly tracked from the iterator to the Object.
501
502 It's also possible to use intrusive containers when the objects to be stored can
503 have different or unknown size. This allows storing base and derived objects
504 in the same container, as shown in the following example:
505
506 [import ../example/doc_window.cpp]
507 [doc_window_code]
508
509 Due to certain properties of intrusive containers
510 they are often more difficult to use than their STL-counterparts. That's why you
511 should avoid them in public interfaces of libraries. Classes to be stored in intrusive
512 containers must change their implementation to store the hook and this is not always
513 possible or desirable.
514
515 [endsect]
516
517 [section:concepts_summary Concept summary]
518
519 Here is a small summary of the basic concepts that will be used in the following
520 chapters:
521
522 [variablelist Brief Concepts Summary
523 [[Node Algorithms][A class containing typedefs and static functions that define
524    basic operations that can be applied to a group of `node`s. It's independent
525    from the node definition and configured using a NodeTraits template
526    parameter that describes the node.]]
527 [[Node Traits][A class that stores basic information and operations to insert a node into a group of nodes.]]
528 [[Hook][A class that a user must add as a base class or as a member to make the user class compatible with intrusive containers. A Hook encapsulates a `node`]]
529 [[Intrusive Container][A class that stores user classes that have the needed hooks. It takes a ValueTraits template parameter as configuration information.]]
530 [[Semi-Intrusive Container][Similar to an intrusive container but a semi-intrusive container needs additional memory (e.g. an auxiliary array) to work.]]
531 [[Value Traits][A class containing typedefs and operations to obtain the node to be used by Node Algorithms from the user class and the inverse.]]
532 ]
533
534 [endsect]
535
536 [section:presenting_containers Presenting Boost.Intrusive containers]
537
538 [*Boost.Intrusive] offers a wide range of intrusive containers:
539
540 *  [*slist]: An intrusive singly linked list. The size overhead is very small
541    for user classes (usually the size of one pointer) but many operations have linear
542    time complexity, so the user must be careful if he wants to avoid performance problems.
543
544 *  [*list]: A `std::list` like intrusive linked list. The size overhead is quite
545    small for user classes (usually the size of two pointers). Many operations have
546    constant time complexity.
547
548 *  [*set/multiset/rbtree]: `std::set/std::multiset` like intrusive associative containers
549    based on red-black trees.
550    The size overhead is moderate for user classes (usually the size of three pointers).
551    Many operations have logarithmic time complexity.
552
553 *  [*avl_set/avl_multiset/avltree]: A `std::set/std::multiset` like intrusive associative
554    containers based on AVL trees.
555    The size overhead is moderate for user classes (usually the size of three pointers).
556    Many operations have logarithmic time complexity.
557
558 *  [*splay_set/splay_multiset/splaytree]: `std::set/std::multiset` like intrusive associative
559    containers based on splay trees. Splay trees have no constant operations, but they
560    have some interesting caching properties.
561    The size overhead is moderate for user classes (usually the size of three pointers).
562    Many operations have logarithmic time complexity.
563
564 *  [*sg_set/sg_multiset/sgtree]: A `std::set/std::multiset` like intrusive associative
565    containers based on scapegoat trees. Scapegoat can be configured with the desired
566    balance factor to achieve the desired rebalancing frequency/search time compromise.
567    The size overhead is moderate for user classes (usually the size of three pointers).
568    Many operations have logarithmic time complexity.
569
570 [*Boost.Intrusive] also offers semi-intrusive containers:
571
572 *  [*unordered_set/unordered_multiset]: `std::tr1::unordered_set/std::tr1::unordered_multiset`
573    like intrusive unordered associative containers.
574    The size overhead is moderate for user classes (an average of two pointers per element).
575    Many operations have amortized constant time complexity.
576
577 Most of these intrusive containers can be configured with constant or linear time
578 size:
579
580 *  [*Linear time size]: The intrusive container doesn't hold a size member that is
581 updated with every insertion/erasure. This implies that the `size()` function doesn't have constant
582 time complexity. On the other hand, the container is smaller, and some operations, like
583 `splice()` taking a range of iterators in linked lists, have constant time complexity
584 instead of linear complexity.
585
586 *  [*Constant time size]: The intrusive container holds a size member that is updated
587 with every insertion/erasure. This implies that the `size()` function has constant time
588 complexity. On the other hand, increases the size of the container, and some operations,
589 like `splice()` taking a range of iterators, have linear time complexity in linked lists.
590
591 To make user classes compatible with these intrusive containers [*Boost.Intrusive]
592 offers two types of hooks for each container type:
593
594 *  [*Base hook]: The hook is stored as a public base class of the user class.
595
596 *  [*Member hook]: The hook is stored as a public member of the user class.
597
598 Apart from that, [*Boost.Intrusive] offers additional features:
599
600 *  [*Safe mode hooks]: Hook constructor initializes the internal `node` to a well-known
601    safe state and intrusive containers check that state before inserting a value in the
602    container using that hook. When erasing an element from the container, the container
603    puts the `node` of the hook in the safe state again. This allows a safer use mode and it can
604    be used to detect programming errors. It implies a slight performance overhead in some
605    operations and can convert some constant time operations to linear time operations.
606
607 *  [*Auto-unlink hooks]: The hook destructor removes the object from the container
608    automatically and the user can safely unlink the object from the container without
609    referring to the container.
610
611 *  [*Non-raw pointers]: If the user wants to use smart pointers instead of raw pointers,
612    [*Boost.Intrusive] hooks can
613    be configured to use any type of pointer. This configuration information is also
614    transmitted to the containers, so all the internal pointers used by intrusive containers
615    configured with these hooks will be smart pointers. As an example,
616    [*Boost.Interprocess] defines a smart pointer compatible with shared memory,
617    called `offset_ptr`. [*Boost.Intrusive] can be configured to use this smart pointer
618    to allow shared memory intrusive containers.
619
620 [endsect]
621
622 [section:safe_hook Safe hooks]
623
624 [section:features Features of the safe mode]
625
626 [*Boost.Intrusive] hooks can be configured to operate in safe-link mode.
627 The safe mode is activated by default, but it can be also explicitly activated:
628
629 [c++]
630
631    //Configuring the safe mode explicitly
632    class Foo : public list_base_hook< link_mode<safe_link> >
633    {};
634
635 With the safe mode the user can detect if the object
636 is actually inserted in a container without any external reference. Let's review the basic features of the safe mode:
637
638 *  Hook's constructor puts the hook in a well-known default state.
639
640 *  Hook's destructor checks if the hook is in the well-known default state. If not,
641    an assertion is raised.
642
643 *  Every time an object is inserted in the intrusive container, the container
644    checks if the hook is in the well-known default state. If not,
645    an assertion is raised.
646
647 *  Every time an object is being erased from the intrusive container, the container
648    puts the erased object in the well-known default state.
649
650 With these features, without any external reference the user can know if the object
651 has been inserted in a container by calling the `is_linked()` member function.
652 If the object is not actually inserted
653 in a container, the hook is in the default state, and if it is inserted in a container, the
654 hook is not in the default state.
655
656 [endsect]
657
658 [section:configuring Configuring safe-mode assertions]
659
660 By default, all safe-mode assertions raised by [*Boost-Intrusive] hooks
661 and containers in are implemented using `BOOST_ASSERT`, which can be configured by
662 the user. See [@http://www.boost.org/libs/utility/assert.html] for more
663 information about `BOOST_ASSERT`.
664
665 `BOOST_ASSERT` is globally configured, so the user might
666 want to redefine intrusive safe-mode assertions without modifying the global
667 `BOOST_ASSERT`. This can be achieved redefining the following macros:
668
669 *  `BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT`: This assertion will be
670    used in insertion functions of the intrusive containers to check that
671    the hook of the value to be inserted is default constructed.
672 *  `BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT`: This assertion will be
673    used in hooks' destructors to check that the hook is in a default state.
674
675 If any of these macros is not redefined, the assertion will default to `BOOST_ASSERT`.
676 If `BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT` or `BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT`
677 is defined and the programmer needs to include a file to configure that assertion, it can define
678 `BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE` or `BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT_INCLUDE`
679 with the name of the file to include:
680
681 [c++]
682
683    #define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT          MYASSERT
684    #define BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT_INCLUDE <myassert.h>
685
686 [endsect]
687
688 [endsect]
689
690 [section:auto_unlink_hooks Auto-unlink hooks]
691
692 [section:auto_unlink_hooks_what What's an auto-unlink hook?]
693
694 [*Boost.Intrusive] offers additional hooks with unique features:
695
696 *  When the destructor of the hook is called, the hook checks if the node is inserted
697    in a container. If so, the hook removes the node from the container.
698 *  The hook has a member function called `unlink()` that can be used to unlink the
699    node from the container at any time, without having any reference to the container,
700    if the user wants to do so.
701
702 These hooks have exactly the same size overhead as their analog non auto-unlinking
703 hooks, but they have a restriction: they can only be used with
704 [link intrusive.presenting_containers non-constant time size containers].
705 There is a reason for this:
706
707 * Auto-unlink hooks don't store any reference to the container where they are inserted.
708 * Only containers with non constant-time `size()` allow removing an object from the container
709   without referring to the container.
710
711 This auto-unlink feature is useful in certain applications
712 but it must be used [*very carefully]:
713
714 *  If several threads are using the same container the destructor of the auto-unlink
715    hook will be called without any thread synchronization so removing the object is
716    thread-unsafe.
717
718 *  Container contents change silently without modifying the container directly.
719    This can lead to surprising effects.
720
721 These auto-unlink hooks have also safe-mode properties:
722
723 *  Hooks' constructors put the hook in a well-known default state.
724
725 *  Every time an object is inserted in the intrusive container, the container
726    checks if the hook is in the well-known default state. If not,
727    an assertion is raised.
728
729 *  Every time an object is erased from an intrusive container, the container
730    puts the erased object in the well-known default state.
731
732 [endsect]
733
734 [section:auto_unlink_hooks_example Auto-unlink hook example]
735
736 Let's see an example of an auto-unlink hook:
737
738 [import ../example/doc_auto_unlink.cpp]
739 [doc_auto_unlink_code]
740
741 [endsect]
742
743 [section:auto_unlink_and_constant_time Auto-unlink hooks and containers with constant-time `size()`]
744
745 As explained, [*Boost.Intrusive] auto-unlink hooks are incompatible with containers
746 that have constant-time `size()`, so if you try to define such container with an
747 auto-unlink hook's value_traits, you will get a static assertion:
748
749 [c++]
750
751    #include <boost/intrusive/list.hpp>
752
753    using boost::intrusive;
754
755    struct MyTag;
756
757    class MyClass : public list_base_hook< link_mode<auto_unlink> >
758    {/**/};
759
760    list <MyClass, constant_time_size<true> > bad_list;
761
762    int main()
763    {
764       bad_list list;
765       return 0;
766    }
767
768 leads to an error similar to:
769
770 [pre
771   error : use of undefined type 'boost::STATIC_ASSERTION_FAILURE<false>'
772 ]
773
774 Pointing to code like this:
775
776 [c++]
777
778    //Constant-time size is incompatible with auto-unlink hooks!
779    BOOST_STATIC_ASSERT(!(constant_time_size && ((int)value_traits::link_mode == (int)auto_unlink)));
780
781 This way, there is no way to compile a program if you try to use auto-unlink hooks
782 in constant-time size containers.
783
784 [endsect]
785
786 [endsect]
787
788 [section:slist Intrusive singly linked list: slist]
789
790 [classref boost::intrusive::slist slist] is the simplest intrusive container of
791 [*Boost.Intrusive]: a singly linked list. The memory overhead
792 it imposes is 1 pointer per node. The size of an empty, non constant-time size
793 [classref boost::intrusive::slist slist] is the size of 1 pointer. This
794 lightweight memory overhead comes with drawbacks, though: many operations have
795 linear time complexity, even some that usually are constant time, like
796 [classref boost::intrusive::slist::swap swap]. [classref boost::intrusive::slist slist]
797 only provides forward iterators.
798
799 For most cases, a doubly linked list is preferable because it offers more
800 constant-time functions with a slightly bigger size overhead.
801 However, for some applications like
802 constructing more elaborate containers, singly linked lists are essential
803 because of their low size overhead.
804
805 [section:slist_hooks slist hooks]
806
807 Like the rest of [*Boost.Intrusive] containers,
808 [classref boost::intrusive::slist slist] has two hook types:
809
810 [c++]
811
812    template <class ...Options>
813    class slist_base_hook;
814
815 *  [classref boost::intrusive::slist_base_hook slist_base_hook]:
816    the user class derives publicly from
817    [classref boost::intrusive::slist_base_hook slist_base_hook] to make
818    it [classref boost::intrusive::slist slist]-compatible.
819
820 [c++]
821
822    template <class ...Options>
823    class slist_member_hook;
824
825 *  [classref boost::intrusive::slist_member_hook slist_member_hook]:
826    the user class contains a public
827    [classref boost::intrusive::slist_member_hook slist_member_hook] to make
828    it [classref boost::intrusive::slist slist]-compatible.
829
830 [classref boost::intrusive::slist_base_hook slist_base_hook] and
831 [classref boost::intrusive::slist_member_hook slist_member_hook]
832 receive the same options explained in
833 the section [link intrusive.usage How to use Boost.Intrusive]:
834
835 *  [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
836    so you can derive from more than one slist hook.
837    Default: `tag<default_tag>`.
838
839 *  [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
840    Default: `link_mode<safe_link>`.
841
842 *  [*`void_pointer<class VoidPointer>`]: The pointer type to be used
843    internally in the hook and propagated to the container.
844    Default: `void_pointer<void*>`.
845
846 [endsect]
847
848 [section:slist_container slist container]
849
850 [c++]
851
852    template <class T, class ...Options>
853    class slist;
854
855 [classref boost::intrusive::slist slist] receives the options explained in
856 the section [link intrusive.usage How to use Boost.Intrusive]:
857
858 *  [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
859    [*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
860    to configure the container. (To learn about value traits go to the section
861    [link intrusive.value_traits Containers with custom ValueTraits].)
862
863 *  [*`constant_time_size<bool Enabled>`]: To activate the constant-time `size()` operation.
864    Default: `constant_time_size<true>`
865
866 *  [*`size_type<typename SizeType>`]: To specify the type that will be used to store the size
867    of the container. Default: `size_type<std::size_t>`.
868
869 [classref boost::intrusive::slist slist] can receive additional options:
870
871 *  [*`linear<bool Enable>`]: the singly linked list is implemented as a
872    null-terminated list instead of a circular list. This allows `O(1)` swap,
873    but losses some operations like `container_from_end_iterator`.
874 *  [*`cache_last<bool Enable>`]: `slist` also stores a pointer to the
875    last element of the singly linked list. This allows `O(1)` swap,
876    `splice_after(iterator, slist &)` and makes the list offer new functions
877    like `push_back(reference)` and `back()`. Logically, the size an empty list is
878    increased in `sizeof(void_pointer)` and the cached last node pointer must
879    be updated in every operation, and that might incur in a slight performance impact.
880
881 `auto_unlink` hooks are not usable if `linear<true>` and/or `cache_last<true>` options are
882 used. If `auto_unlink` hooks are used and those options are specified, a static
883 assertion will be raised.
884
885 [endsect]
886
887 [section:slist_example Example]
888
889 Now let's see a small example using both hooks:
890
891 [import ../example/doc_slist.cpp]
892 [doc_slist_code]
893
894 [endsect]
895
896 [endsect]
897
898 [section:list Intrusive doubly linked list: list]
899
900 [classref boost::intrusive::list list] is a doubly linked list. The memory overhead
901 it imposes is 2 pointers per node. An empty, non constant-time size [classref boost::intrusive::list list]
902 also has the size of 2 pointers. [classref boost::intrusive::list list]
903 has many more constant-time operations than [classref boost::intrusive::slist slist]
904 and provides a bidirectional iterator. It is recommended to use
905 [classref boost::intrusive::list list] instead of
906 [classref boost::intrusive::slist slist] if the size overhead is acceptable:
907
908 [section:list_hooks list hooks]
909
910 Like the rest of [*Boost.Intrusive] containers,
911 [classref boost::intrusive::list list] has two hook types:
912
913 [c++]
914
915    template <class ...Options>
916    class list_base_hook;
917
918 *  [classref boost::intrusive::list_base_hook list_base_hook]: the user class
919    derives publicly from [classref boost::intrusive::list_base_hook list_base_hook]
920    to make it [classref boost::intrusive::list list]-compatible.
921
922 [c++]
923
924    template <class ...Options>
925    class list_member_hook;
926
927 *  [classref boost::intrusive::list_member_hook list_member_hook]:
928    the user class contains a public
929    [classref boost::intrusive::list_member_hook list_member_hook] to make
930    it [classref boost::intrusive::list list]-compatible.
931
932 [classref boost::intrusive::list_base_hook list_base_hook] and
933 [classref boost::intrusive::list_member_hook list_member_hook] receive
934 the same options explained in the section
935 [link intrusive.usage How to use Boost.Intrusive]:
936
937 *  [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
938    so you can derive from more than one list hook.
939    Default: `tag<default_tag>`.
940
941 *  [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
942    Default: `link_mode<safe_link>`.
943
944 *  [*`void_pointer<class VoidPointer>`]: The pointer type to be used
945    internally in the hook and propagated to the container.
946    Default: `void_pointer<void*>`.
947
948 [endsect]
949
950 [section:list_container list container]
951
952 [c++]
953
954    template <class T, class ...Options>
955    class list;
956
957 [classref boost::intrusive::list list] receives the same options explained in
958 the section [link intrusive.usage How to use Boost.Intrusive]:
959
960 *  [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
961    [*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
962    to configure the container. (To learn about value traits go to the section
963    [link intrusive.value_traits Containers with custom ValueTraits].)
964
965 *  [*`constant_time_size<bool Enabled>`]: To activate the constant-time `size()` operation.
966    Default: `constant_time_size<true>`
967
968 *  [*`size_type<typename SizeType>`]: To specify the type that will be used to store the size
969    of the container. Default: `size_type<std::size_t>`
970
971 [endsect]
972
973 [section:list_example Example]
974
975 Now let's see a small example using both hooks:
976
977 [import ../example/doc_list.cpp]
978 [doc_list_code]
979
980 [endsect]
981
982 [endsect]
983
984 [section:set_multiset Intrusive associative containers: set, multiset, rbtree]
985
986 [*Boost.Intrusive] also offers associative containers that can be very useful
987 when creating more complex associative containers, like containers maintaining
988 one or more indices with different sorting semantics. Boost.Intrusive associative
989 containers, like most STL associative container implementations are based on
990 red-black trees.
991
992 The memory overhead of these containers is usually 3 pointers and a bit (with
993 alignment issues, this means 3 pointers and an integer).
994 This size can be reduced to 3 pointers if pointers have even alignment
995 (which is usually true in most systems).
996
997 An empty, non constant-time size [classref boost::intrusive::set set],
998 [classref boost::intrusive::multiset multiset] or
999 [classref boost::intrusive::rbtree rbtree]
1000 has also the size of 3 pointers and an integer (3 pointers when optimized for size).
1001 These containers have logarithmic complexity in many
1002 operations like
1003 searches, insertions, erasures, etc. [classref boost::intrusive::set set] and
1004 [classref boost::intrusive::multiset multiset] are the
1005 intrusive equivalents of standard `std::set` and `std::multiset` containers.
1006
1007 [classref boost::intrusive::rbtree rbtree] is a superset of
1008 [classref boost::intrusive::set set] and
1009 [classref boost::intrusive::multiset multiset] containers that offers
1010 functions to insert unique and multiple keys.
1011
1012 [section:set_multiset_hooks set, multiset and rbtree hooks]
1013
1014 [classref boost::intrusive::set set],
1015 [classref boost::intrusive::multiset multiset] and
1016 [classref boost::intrusive::rbtree rbtree] share the same hooks.
1017 This is an advantage, because the same
1018 user type can be inserted first in a [classref boost::intrusive::multiset multiset]
1019 and after that in [classref boost::intrusive::set set] without
1020 changing the definition of the user class.
1021
1022 [c++]
1023
1024    template <class ...Options>
1025    class set_base_hook;
1026
1027 *  [classref boost::intrusive::set_base_hook set_base_hook]:
1028    the user class derives publicly from
1029    [classref boost::intrusive::set_base_hook set_base_hook] to make
1030    it [classref boost::intrusive::set set]/[classref boost::intrusive::multiset multiset]-compatible.
1031
1032 [c++]
1033
1034    template <class ...Options>
1035    class set_member_hook;
1036
1037 *  [classref boost::intrusive::set_member_hook set_member_hook]:
1038    the user class contains a public
1039    [classref boost::intrusive::set_member_hook set_member_hook] to make
1040    it [classref boost::intrusive::set set]/[classref boost::intrusive::multiset multiset]-compatible.
1041
1042 [classref boost::intrusive::set_base_hook set_base_hook] and
1043 [classref boost::intrusive::set_member_hook set_member_hook] receive
1044 the same options explained in the section
1045 [link intrusive.usage How to use Boost.Intrusive] plus a size optimization option:
1046
1047 *  [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
1048    so you can derive from more than one base hook.
1049    Default: `tag<default_tag>`.
1050
1051 *  [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
1052    Default: `link_mode<safe_link>`.
1053
1054 *  [*`void_pointer<class VoidPointer>`]: The pointer type to be used
1055    internally in the hook and propagated to the container.
1056    Default: `void_pointer<void*>`.
1057
1058 *  [*`optimize_size<bool Enable>`]: The hook will be optimized for size
1059    instead of speed. The hook will embed the color bit of the red-black
1060    tree node in the parent pointer if pointer alignment is even.
1061    In some platforms, optimizing the size might reduce speed performance a bit
1062    since masking operations will be needed to access parent pointer and color attributes,
1063    in other platforms this option improves performance due to improved memory locality.
1064    Default: `optimize_size<false>`.
1065
1066 [endsect]
1067
1068 [section:set_multiset_containers set, multiset and rbtree containers]
1069
1070 [c++]
1071
1072    template <class T, class ...Options>
1073    class set;
1074
1075    template <class T, class ...Options>
1076    class multiset;
1077
1078    template <class T, class ...Options>
1079    class rbtree;
1080
1081 These containers receive the same options explained in the section
1082 [link intrusive.usage How to use Boost.Intrusive]:
1083
1084 *  [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
1085    [*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
1086    to configure the container. (To learn about value traits go to the section
1087    [link intrusive.value_traits Containers with custom ValueTraits].)
1088
1089 *  [*`constant_time_size<bool Enabled>`]: To activate the constant-time `size()` operation.
1090    Default: `constant_time_size<true>`
1091
1092 *  [*`size_type<typename SizeType>`]: To specify the type that will be used to store the size
1093    of the container. Default: `size_type<std::size_t>`
1094
1095 And they also can receive an additional option:
1096
1097 *  [*`compare<class Compare>`]: Comparison function for the objects to be inserted
1098    in containers. The comparison functor must induce a strict weak ordering.
1099    Default: `compare< std::less<key_type> >`
1100
1101 *  [*`key_of_value<class KeyOfValueFunctionObject>`]: A function object that will
1102    define the `key_type` of the value type to be stored. This type will allow a map-like interface. See
1103    [link intrusive.map_multimap Map and multimap-like interface with set and multiset]
1104    for details. Default: `key_type` is equal to `value_type` (set-like interface).
1105
1106 [endsect]
1107
1108 [section:set_multiset_example Example]
1109
1110 Now let's see a small example using both hooks and both containers:
1111
1112 [import ../example/doc_set.cpp]
1113 [doc_set_code]
1114
1115 [endsect]
1116
1117 [endsect]
1118
1119 [section:unordered_set_unordered_multiset Semi-Intrusive unordered associative containers: unordered_set, unordered_multiset]
1120
1121 [*Boost.Intrusive] also offers hashed containers that can be very useful to implement
1122 fast-lookup containers.  These containers
1123 ([classref boost::intrusive::unordered_set unordered_set] and [classref boost::intrusive::unordered_multiset unordered_multiset])
1124 are semi-intrusive containers: they need additional memory apart from the hook
1125 stored in the `value_type`. This additional
1126 memory must be passed in the constructor of the container.
1127
1128 Unlike C++ TR1 unordered associative containers (which are also hashed containers),
1129 the contents of these semi-intrusive containers are not rehashed to maintain a
1130 load factor: that would require memory management and intrusive containers don't
1131 implement any memory management at all. However, the user can request an explicit
1132 rehashing passing a new bucket array.
1133 This also offers an additional guarantee over TR1 unordered associative containers:
1134 [*iterators are not invalidated when inserting an element] in the container.
1135
1136 As with TR1 unordered associative containers, rehashing invalidates iterators,
1137 changes ordering between elements and changes which buckets elements appear in,
1138 but does not invalidate pointers or references to elements.
1139
1140 Apart from expected hash and equality function objects, [*Boost.Intrusive] unordered
1141 associative containers' constructors take an argument specifying an auxiliary
1142 bucket vector to be used by the container.
1143
1144 [section:unordered_set_unordered_multiset_performance unordered_set and unordered_multiset performance notes]
1145
1146 The size overhead for a hashed container is moderate: 1 pointer per value plus
1147 a bucket array per container. The size of an element of the bucket array
1148 is usually one pointer. To obtain a good performance hashed container,
1149 the bucket length is usually the same as the number of elements that the
1150 container contains, so a well-balanced hashed container (`bucket_count()` is
1151 equal to `size()` ) will have an equivalent overhead of two pointers per element.
1152
1153 An empty, non constant-time size [classref boost::intrusive::unordered_set unordered_set] or
1154 [classref boost::intrusive::unordered_multiset unordered_multiset]
1155 has also the size of `bucket_count()` pointers.
1156
1157 Insertions, erasures, and searches, have amortized constant-time complexity in
1158 hashed containers. However, some worst-case guarantees are linear. See
1159 [classref boost::intrusive::unordered_set unordered_set] or
1160 [classref boost::intrusive::unordered_multiset unordered_multiset] for complexity guarantees
1161 of each operation.
1162
1163 [*Be careful with non constant-time size hashed containers]: some operations, like
1164 `empty()`, have linear complexity, unlike other [*Boost.Intrusive] containers.
1165
1166 [endsect]
1167
1168 [section:unordered_set_unordered_multiset_hooks unordered_set and unordered_multiset hooks]
1169
1170 [classref boost::intrusive::unordered_set unordered_set] and [classref boost::intrusive::unordered_multiset unordered_multiset] share the same hooks. This is an advantage, because the same
1171 user type can be inserted first in a [classref boost::intrusive::unordered_multiset unordered_multiset] and after that in [classref boost::intrusive::unordered_set unordered_set] without
1172 changing the definition of the user class.
1173
1174 [c++]
1175
1176    template <class ...Options>
1177    class unordered_set_base_hook;
1178
1179 *  [classref boost::intrusive::unordered_set_base_hook unordered_set_base_hook]:
1180    the user class derives publicly from
1181    [classref boost::intrusive::unordered_set_base_hook unordered_set_base_hook] to make
1182    it [classref boost::intrusive::unordered_set unordered_set]/[classref boost::intrusive::unordered_multiset unordered_multiset]-compatible.
1183
1184 [c++]
1185
1186    template <class ...Options>
1187    class unordered_set_member_hook;
1188
1189 *  [classref boost::intrusive::unordered_set_member_hook unordered_set_member_hook]:
1190    the user class contains a public
1191    [classref boost::intrusive::unordered_set_member_hook unordered_set_member_hook] to make
1192    it [classref boost::intrusive::unordered_set unordered_set]/[classref boost::intrusive::unordered_multiset unordered_multiset]-compatible.
1193
1194 [classref boost::intrusive::unordered_set_base_hook unordered_set_base_hook] and
1195 [classref boost::intrusive::unordered_set_member_hook unordered_set_member_hook] receive
1196 the same options explained in the section
1197 [link intrusive.usage How to use Boost.Intrusive]:
1198
1199 *  [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
1200    so you can derive from more than one base hook.
1201    Default: `tag<default_tag>`.
1202
1203 *  [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
1204    Default: `link_mode<safe_link>`.
1205
1206 *  [*`void_pointer<class VoidPointer>`]: The pointer type to be used
1207    internally in the hook and propagated to the container.
1208    Default: `void_pointer<void*>`.
1209
1210 Apart from them, these hooks offer additional options:
1211
1212 *  [*`store_hash<bool Enabled>`]: This option reserves additional space in
1213    the hook to store the hash value of the object once it's introduced in the
1214    container. When this option is used, the unordered container will store
1215    the calculated hash value in the hook and rehashing operations won't need
1216    to recalculate the hash of the value.
1217    This option will improve the performance of unordered containers when
1218    rehashing is frequent or hashing the value is a slow operation.
1219    Default: `store_hash<false>`.
1220
1221 *  [*`optimize_multikey<bool Enabled>`]: This option reserves additional space in
1222    the hook that will be used to group equal elements in unordered multisets,
1223    improving significantly the performance when many equal values are inserted
1224    in these containers. Default: `optimize_multikey<false>`.
1225
1226 [endsect]
1227
1228 [section:unordered_set_unordered_multiset_containers unordered_set and unordered_multiset containers]
1229
1230 [c++]
1231
1232    template<class T, class ...Options>
1233    class unordered_set;
1234
1235    template<class T, class ...Options>
1236    class unordered_multiset;
1237
1238 As mentioned, unordered containers need an auxiliary array to work. [*Boost.Intrusive]
1239 unordered containers receive this auxiliary array packed in a type called `bucket_traits`
1240 (which can be also customized by a container option). All unordered containers receive
1241 a `bucket_traits` object in their constructors. The default `bucket_traits` class
1242 is initialized with a pointer to an array of buckets and its size:
1243
1244 [c++]
1245
1246    #include <boost/intrusive/unordered_set.hpp>
1247
1248    using namespace boost::intrusive;
1249
1250    struct MyClass : public unordered_set_base_hook<>
1251    {};
1252
1253    typedef unordered_set<MyClass>::bucket_type     bucket_type;
1254    typedef unordered_set<MyClass>::bucket_traits   bucket_traits;
1255
1256    int main()
1257    {
1258       bucket_type buckets[100];
1259       unordered_set<MyClass> uset(bucket_traits(buckets, 100));
1260       return 0;
1261    }
1262
1263 Each hashed container needs [*its own bucket traits], that is, [*its own
1264 bucket vector]. Two hashed containers
1265 [*can't] share the same `bucket_type` elements. The bucket array [*must] be
1266 destroyed [*after] the container using it is destroyed, otherwise, the result
1267 is undefined.
1268
1269 [classref boost::intrusive::unordered_set unordered_set] and
1270 [classref boost::intrusive::unordered_multiset unordered_multiset]
1271 receive the same options explained in the section
1272 [link intrusive.usage How to use Boost.Intrusive]:
1273
1274 *  [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
1275    [*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
1276    to configure the container. (To learn about value traits go to the section
1277    [link intrusive.value_traits Containers with custom ValueTraits].)
1278
1279 *  [*`constant_time_size<bool Enabled>`]: To activate the constant-time `size()` operation.
1280    Default: `constant_time_size<true>`
1281
1282 *  [*`size_type<typename SizeType>`]: To specify the type that will be used to store the size
1283    of the container. Default: `size_type<std::size_t>`
1284
1285 And they also can receive additional options:
1286
1287 *  [*`equal<class Equal>`]: Equality function for the objects to be inserted
1288    in containers. Default: `equal< std::equal_to<T> >`
1289
1290 *  [*`hash<class Hash>`]: Hash function to be used in the container.
1291    Default: `hash< boost::hash<T> >`
1292
1293 *  [*`bucket_traits<class BucketTraits>`]: A type that wraps the bucket vector to
1294    be used by the unordered container. Default: a type initialized by the address
1295    and size of a bucket array and stores both variables internally.
1296
1297 *  [*`power_2_buckets<bool Enabled>`]: The user guarantees that only bucket arrays
1298    with power of two length will be used. The container will then use masks instead of modulo
1299    operations to obtain the bucket number from the hash value. Masks are faster than
1300    modulo operations and for some applications modulo operations can impose
1301    a considerable overhead. In debug mode an assertion will be raised if the user
1302    provides a bucket length that is not power of two.
1303    Default: `power_2_buckets<false>`.
1304
1305 *  [*`cache_begin<bool Enabled>`]:
1306    [*Note: this option is not compatible with `auto_unlink` hooks].
1307    Due to its internal structure, finding the first
1308    element of an unordered container (`begin()` operation) is
1309    amortized constant-time. It's possible to speed up `begin()` and other operations
1310    related to it (like `clear()`) if the container caches internally the position
1311    of the first element. This imposes the overhead of one pointer to the size
1312    of the container. Default: `cache_begin<false>`.
1313
1314 *  [*`compare_hash<bool Enabled>`]:
1315    [*Note: this option requires `store_hash<true>` option in the hook].
1316    When the comparison function is expensive,
1317    (e.g. strings with a long common predicate) sometimes (specially when the
1318    load factor is high or we have many equivalent elements in an
1319    [classref boost::intrusive::unordered_multiset unordered_multiset] and
1320    no `optimize_multikey<>` is activated in the hook)
1321    the equality function is a performance problem. Two equal values must have
1322    equal hashes, so comparing the hash values of two elements before using the
1323    comparison functor can speed up some implementations.
1324
1325 *  [*`incremental<bool Enabled>`]: Activates incremental hashing (also known as Linear Hashing).
1326    This option implies `power_2_buckets<true>` and the container will require power of two buckets.
1327    For more information on incremental hashing, see
1328    [@http://en.wikipedia.org/wiki/Linear_hashing `Linear hash` on Wikipedia]
1329    Default: `incremental<false>`
1330
1331 *  [*`key_of_value<class KeyOfValueFunctionObject>`]: A function object that will
1332    define the `key_type` of the value type to be stored. This type will allow a map-like interface. See
1333    [link intrusive.map_multimap Map and multimap-like interface with set and multiset]
1334    for details. Default: `key_type` is equal to `value_type` (set-like interface).
1335
1336 [endsect]
1337
1338 [section:unordered_set_unordered_multiset_example Example]
1339
1340 Now let's see a small example using both hooks and both containers:
1341
1342 [import ../example/doc_unordered_set.cpp]
1343 [doc_unordered_set_code]
1344
1345 [endsect]
1346
1347 [section:custom_bucket_traits Custom bucket traits]
1348
1349 Instead of using the default `bucket_traits` class to store the bucket array, a user
1350 can define his own class to store the bucket array using the [*['bucket_traits<>]]
1351 option. A user-defined bucket-traits must fulfill the following interface:
1352
1353 [c++]
1354
1355    class my_bucket_traits
1356    {
1357       bucket_ptr        bucket_begin();
1358       const_bucket_ptr  bucket_begin() const;
1359       std::size_t bucket_count() const;
1360    };
1361
1362
1363 The following bucket traits just stores a pointer to the bucket
1364 array but the size is a compile-time constant. Note the use of the auxiliary
1365 [classref boost::intrusive::unordered_bucket unordered_bucket] and
1366 [classref boost::intrusive::unordered_bucket_ptr unordered_bucket_ptr]
1367 utilities to obtain the type of the bucket and its pointer before defining
1368 the unordered container:
1369
1370 [import ../example/doc_bucket_traits.cpp]
1371 [doc_bucket_traits]
1372
1373 [endsect]
1374
1375 [endsect]
1376
1377 [section:map_multimap Map and multimap-like interface for associative containers]
1378
1379 Implementing map-like intrusive containers is not a trivial task as
1380 STL's `std::map` and `std::multimap` containers store copies of a `value_type` which is defined
1381 as `std::pair<const key_type, mapped_type>`. In order to reproduce this interface in [*Boost.Intrusive]
1382 it shall require that objects stored in the intrusive containers contain that `std::pair` member with
1383 `pair.first` hardcoded as the key part and `pair.second` hardcoded as the `mapped_type`, which
1384 is limiting and also not very useful in practice. Any intrusive associative container can be used like
1385 a map using [link intrusive.advanced_lookups_insertions advanced lookup and insertions] and the user
1386 can change the key type in each lookup/insertion check call.
1387
1388 On the other hand, in many cases containers are indexed by a well-known key type, and the user is forced
1389 to write some repetitive code using advanced lookup and insertions. [*Boost.Intrusive]
1390 associative containers offer an alternative to build a useful map-like lookup interfaces
1391 without forcing users to define `value_type`s containing `std::pair`-like classes.
1392 The option is called [classref boost::intrusive::key_of_value].
1393
1394 If a user specifies that option when defining a `set/multiset` intrusive container, it specifies a function object
1395 that will tell the container which is the type of the ['key] that `value_type` holds and how to obtain it. This
1396 function object must be:
1397
1398 * Lightweight to copy.
1399 * Default constructible (when the container constructor overload requires it).
1400 * It shall define:
1401    * A `type` member that defines the type of the key
1402    * A member function that returns the key derived a `value_type`, either by value or by const-reference.
1403
1404 Let's see an example of how a set can be configured as a map indexed by an integer stored in the `value_type`:
1405  
1406 [import ../example/doc_map.cpp]
1407 [doc_map_code]
1408
1409 [endsect]
1410
1411 [section:avl_set_multiset Intrusive avl tree based associative containers: avl_set, avl_multiset and avltree]
1412
1413 Similar to red-black trees, AVL trees are balanced binary trees.
1414 AVL trees are often compared with red-black trees because they support the same set of operations
1415 and because both take O(log n) time for basic operations.
1416 AVL trees are more rigidly balanced than Red-Black trees, leading to slower insertion and
1417 removal but faster retrieval, so AVL trees perform better
1418 than red-black trees for lookup-intensive applications.
1419
1420 [*Boost.Intrusive] offers 3 containers based on avl trees:
1421 [classref boost::intrusive::avl_set avl_set],
1422 [classref boost::intrusive::avl_multiset avl_multiset] and
1423 [classref boost::intrusive::avltree avltree]. The first two are similar to
1424 [classref boost::intrusive::set set] or
1425 [classref boost::intrusive::multiset multiset] and the latter is a generalization
1426 that offers functions both to insert unique and multiple keys.
1427
1428 The memory overhead of these containers with Boost.Intrusive hooks is usually 3
1429 pointers and 2 bits (due to alignment, this usually means 3 pointers plus an integer).
1430 This size can be reduced to 3 pointers if pointers have 4 byte alignment
1431 (which is usually true in 32 bit systems).
1432
1433 An empty, non constant-time size [classref boost::intrusive::avl_set avl_set],
1434 [classref boost::intrusive::avl_multiset avl_multiset] or
1435 [classref boost::intrusive::avltree avltree]
1436 also has a size of 3 pointers and an integer (3 pointers when optimized for size).
1437
1438 [section:avl_set_multiset_hooks avl_set, avl_multiset and avltree hooks]
1439
1440 [classref boost::intrusive::avl_set avl_set],
1441 [classref boost::intrusive::avl_multiset avl_multiset] and
1442 [classref boost::intrusive::avltree avltree]
1443 share the same hooks.
1444
1445 [c++]
1446
1447    template <class ...Options>
1448    class avl_set_base_hook;
1449
1450 *  [classref boost::intrusive::avl_set_base_hook avl_set_base_hook]:
1451    the user class derives publicly from this class to make
1452    it compatible with avl tree based containers.
1453
1454 [c++]
1455
1456    template <class ...Options>
1457    class avl_set_member_hook;
1458
1459 *  [classref boost::intrusive::set_member_hook set_member_hook]:
1460    the user class contains a public member of this class to make
1461    it compatible with avl tree based containers.
1462
1463 [classref boost::intrusive::avl_set_base_hook avl_set_base_hook] and
1464 [classref boost::intrusive::avl_set_member_hook avl_set_member_hook] receive
1465 the same options explained in the section
1466 [link intrusive.usage How to use Boost.Intrusive] plus an option to optimize
1467 the size of the node:
1468
1469 *  [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
1470    so you can derive from more than one base hook.
1471    Default: `tag<default_tag>`.
1472
1473 *  [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
1474    Default: `link_mode<safe_link>`.
1475
1476 *  [*`void_pointer<class VoidPointer>`]: The pointer type to be used
1477    internally in the hook and propagated to the container.
1478    Default: `void_pointer<void*>`.
1479
1480 *  [*`optimize_size<bool Enable>`]: The hook will be optimized for size
1481    instead of speed. The hook will embed the balance bits of the AVL
1482    tree node in the parent pointer if pointer alignment is multiple of 4.
1483    In some platforms, optimizing the size might reduce speed performance a bit
1484    since masking operations will be needed to access parent pointer and balance factor attributes,
1485    in other platforms this option improves performance due to improved memory locality.
1486    Default: `optimize_size<false>`.
1487
1488 [endsect]
1489
1490 [section:set_multiset_containers avl_set, avl_multiset and avltree containers]
1491
1492 [c++]
1493
1494    template <class T, class ...Options>
1495    class avl_set;
1496
1497    template <class T, class ...Options>
1498    class avl_multiset;
1499
1500    template <class T, class ...Options>
1501    class avltree;
1502
1503 These containers receive the same options explained in the section
1504 [link intrusive.usage How to use Boost.Intrusive]:
1505
1506 *  [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
1507    [*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
1508    to configure the container. (To learn about value traits go to the section
1509    [link intrusive.value_traits Containers with custom ValueTraits].)
1510
1511 *  [*`constant_time_size<bool Enabled>`]: To activate the constant-time `size()` operation.
1512    Default: `constant_time_size<true>`
1513
1514 *  [*`size_type<typename SizeType>`]: To specify the type that will be used to store the size
1515    of the container. Default: `size_type<std::size_t>`
1516
1517 And they also can receive an additional option:
1518
1519 *  [*`compare<class Compare>`]: Comparison function for the objects to be inserted
1520    in containers. The comparison functor must induce a strict weak ordering.
1521    Default: `compare< std::less<key_type> >`
1522
1523 *  [*`key_of_value<class KeyOfValueFunctionObject>`]: A function object that will
1524    define the `key_type` of the value type to be stored. This type will allow a map-like interface. See
1525    [link intrusive.map_multimap Map and multimap-like interface with set and multiset]
1526    for details. Default: `key_type` is equal to `value_type` (set-like interface).
1527
1528 [endsect]
1529
1530 [section:avl_set_multiset_example Example]
1531
1532 Now let's see a small example using both hooks and
1533 [classref boost::intrusive::avl_set avl_set]/
1534 [classref boost::intrusive::avl_multiset avl_multiset]
1535 containers:
1536
1537 [import ../example/doc_avl_set.cpp]
1538 [doc_avl_set_code]
1539
1540 [endsect]
1541
1542 [endsect]
1543
1544 [section:splay_set_multiset Intrusive splay tree based associative containers: splay_set, splay_multiset and , splay_tree]
1545
1546 C++ associative containers are usually based on red-black tree implementations (e.g.: STL,
1547 Boost.Intrusive associative containers). However, there are other interesting data
1548 structures that offer some advantages (and also disadvantages).
1549
1550 Splay trees are self-adjusting binary search trees used typically in caches, memory
1551 allocators and other applications, because splay trees have a "caching effect": recently
1552 accessed elements have better access times than elements accessed less frequently.
1553 For more information on splay trees see [@http://en.wikipedia.org/wiki/Splay_tree the corresponding Wikipedia entry].
1554
1555 [*Boost.Intrusive] offers 3 containers based on splay trees:
1556 [classref boost::intrusive::splay_set splay_set],
1557 [classref boost::intrusive::splay_multiset splay_multiset] and
1558 [classref boost::intrusive::splaytree splaytree]. The first two are similar to
1559 [classref boost::intrusive::set set] or
1560 [classref boost::intrusive::multiset multiset] and the latter is a generalization
1561 that offers functions both to insert unique and multiple keys.
1562
1563 The memory overhead of these containers with Boost.Intrusive hooks is usually 3 pointers.
1564 An empty, non constant-time size splay container has also a size of 3 pointers.
1565
1566 [section:splay_set_multiset_disadvantages Advantages and disadvantages of splay tree based containers]
1567
1568 Splay tree based intrusive containers have logarithmic complexity in many
1569 operations like searches, insertions, erasures, etc., but if some elements are
1570 more frequently accessed than others, splay trees perform faster searches than equivalent
1571 balanced binary trees (such as red-black trees).
1572
1573 The caching effect offered by splay trees comes with a cost: the tree must be
1574 rebalanced when an element is searched. To maintain const-correctness and thread-safety
1575 guarantees, this caching effect is not updated when const versions of
1576 search functions like `find()`, `lower_bound()`, `upper_bound()`, `equal_range()`,
1577 `count()`... are called. This means that using splay-tree based associative containers as drop-in
1578 replacements of [classref boost::intrusive::set set]/
1579 [classref boost::intrusive::multiset multiset], specially for const search functions,
1580 might not result in desired performance improvements.
1581
1582 If element searches are randomized, the tree will be continuously srebalanced
1583 without taking advantage of the cache effect, so splay trees can offer worse
1584 performance than other balanced trees for several search patterns.
1585
1586 [*Boost.Intrusive] splay associative containers don't use their own hook types but plain Binary search tree hooks.
1587 See [link intrusive.bst_hooks Binary search tree hooks: bs_set_base_hook and bs_set_member_hook] section for more
1588 information about these hooks.
1589
1590 [endsect]
1591
1592 [section:set_multiset_containers splay_set, splay_multiset and splaytree containers]
1593
1594 [c++]
1595
1596    template <class T, class ...Options>
1597    class splay_set;
1598
1599    template <class T, class ...Options>
1600    class splay_multiset;
1601
1602    template <class T, class ...Options>
1603    class splaytree;
1604
1605 These containers receive the same options explained in the section
1606 [link intrusive.usage How to use Boost.Intrusive]:
1607
1608 *  [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
1609    [*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
1610    to configure the container.  (To learn about value traits go to the section
1611    [link intrusive.value_traits Containers with custom ValueTraits].)
1612
1613 *  [*`constant_time_size<bool Enabled>`]: To activate the constant-time `size()` operation.
1614    Default: `constant_time_size<true>`
1615
1616 *  [*`size_type<typename SizeType>`]: To specify the type that will be used to store the size
1617    of the container. Default: `size_type<std::size_t>`
1618
1619 And they also can receive an additional option:
1620
1621 *  [*`compare<class Compare>`]: Comparison function for the objects to be inserted
1622    in containers. The comparison functor must induce a strict weak ordering.
1623    Default: `compare< std::less<key_type> >`
1624
1625 *  [*`key_of_value<class KeyOfValueFunctionObject>`]: A function object that will
1626    define the `key_type` of the value type to be stored. This type will allow a map-like interface. See
1627    [link intrusive.map_multimap Map and multimap-like interface with set and multiset]
1628    for details. Default: `key_type` is equal to `value_type` (set-like interface).
1629
1630 [endsect]
1631
1632 [section:splay_set_multiset_example Example]
1633
1634 Now let's see a small example using
1635 [classref boost::intrusive::splay_set splay_set]/
1636 [classref boost::intrusive::splay_multiset splay_multiset]
1637 containers:
1638
1639 [import ../example/doc_splay_set.cpp]
1640 [doc_splay_set_code]
1641
1642 [endsect]
1643
1644 [endsect]
1645
1646
1647 [section:sg_set_multiset Intrusive scapegoat tree based associative containers: sg_set, sg_multiset and sgtree]
1648
1649 A scapegoat tree is a self-balancing binary search tree, that provides worst-case O(log n)
1650 lookup time, and O(log n) amortized insertion and deletion time.
1651 Unlike other self-balancing binary search trees that provide worst case O(log n) lookup
1652 time, scapegoat trees have no additional per-node overhead compared to a regular binary
1653 search tree.
1654
1655 A binary search tree is said to be weight balanced if half the nodes are on the left
1656 of the root, and half on the right. An a-height-balanced tree is defined with defined
1657 with the following equation:
1658
1659 [*['height(tree) <= log1/a(tree.size())]]
1660
1661 *  [*['a == 1]]: A tree forming a linked list is considered balanced.
1662 *  [*['a == 0.5]]: Only a perfectly balanced binary is considered balanced.
1663
1664 Scapegoat trees are loosely ['a-height-balanced] so:
1665
1666 [*['height(tree) <= log1/a(tree.size()) + 1]]
1667
1668 Scapegoat trees support any a between 0.5 and 1. If a is higher, the tree is rebalanced
1669 less often, obtaining quicker insertions but slower searches. Lower
1670 a values improve search times. Scapegoat-trees implemented in [*Boost.Intrusive] offer the possibility of
1671 [*changing a at run-time] taking advantage of the flexibility of scapegoat trees.
1672 For more information on scapegoat trees see [@http://en.wikipedia.org/wiki/Scapegoat_tree Wikipedia entry].
1673
1674 Scapegoat trees also have downsides:
1675
1676 *  They need additional storage of data on the
1677    root (the size of the tree, for example) to achieve logarithmic complexity operations
1678    so it's not possible to offer `auto_unlink` hooks. The size of an empty scapegoat
1679    tree is also considerably increased.
1680
1681 *  The operations needed to determine if the tree is unbalanced require floating-point
1682    operations like ['log1/a]. If the system has no floating point operations (like some
1683    embedded systems), scapegoat tree operations might become slow.
1684
1685 [*Boost.Intrusive] offers 3 containers based on scapegoat trees:
1686 [classref boost::intrusive::sg_set sg_set],
1687 [classref boost::intrusive::sg_multiset sg_multiset] and
1688 [classref boost::intrusive::sgtree sgtree]. The first two are similar to
1689 [classref boost::intrusive::set set] or
1690 [classref boost::intrusive::multiset multiset] and the latter is a generalization
1691 that offers functions both to insert unique and multiple keys.
1692
1693 The memory overhead of these containers with Boost.Intrusive hooks is 3
1694 pointers.
1695
1696 An empty, [classref boost::intrusive::sg_set sg_set],
1697 [classref boost::intrusive::sg_multiset sg_multiset] or
1698 [classref boost::intrusive::sgtree sgtree]
1699 has also the size of 3 pointers, two integers and two floating point values
1700 (equivalent to the size of 7 pointers on most systems).
1701
1702 [*Boost.Intrusive] scapegoat associative containers don't use their own hook types but plain Binary search tree hooks.
1703 See [link intrusive.bst_hooks Binary search tree hooks: bs_set_base_hook and bs_set_member_hook] section for more
1704 information about these hooks.
1705
1706 [section:sg_set_multiset_containers sg_set, sg_multiset and sgtree containers]
1707
1708 [c++]
1709
1710    template <class T, class ...Options>
1711    class sg_set;
1712
1713    template <class T, class ...Options>
1714    class sg_multiset;
1715
1716    template <class T, class ...Options>
1717    class sgtree;
1718
1719 These containers receive the same options explained in the section
1720 [link intrusive.usage How to use Boost.Intrusive]:
1721
1722 *  [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
1723    [*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
1724    to configure the container. (To learn about value traits go to the section
1725    [link intrusive.value_traits Containers with custom ValueTraits].)
1726
1727 *  [*`size_type<typename SizeType>`]: To specify the type that will be used to store the size
1728    of the container. Default: `size_type<std::size_t>`
1729
1730 And they also can receive additional options:
1731
1732 *  [*`compare<class Compare>`]: Comparison function for the objects to be inserted
1733    in containers. The comparison functor must induce a strict weak ordering.
1734    Default: `compare< std::less<key_type> >`
1735
1736 *  [*`floating_point<bool Enable>`]:
1737    When this option is deactivated, the scapegoat tree loses the ability to change
1738    the balance factor a at run-time, but the size of an empty container is reduced
1739    and no floating point operations are performed, normally increasing container
1740    performance. The fixed a factor that is used when this option is activated
1741    is ['1/sqrt(2) ~ 0,70711]. Default: `floating_point<true>`
1742
1743 *  [*`key_of_value<class KeyOfValueFunctionObject>`]: A function object that will
1744    define the `key_type` of the value type to be stored. This type will allow a map-like interface. See
1745    [link intrusive.map_multimap Map and multimap-like interface with set and multiset]
1746    for details. Default: `key_type` is equal to `value_type` (set-like interface).
1747
1748 [endsect]
1749
1750 [section:sg_set_multiset_example Example]
1751
1752 Now let's see a small example using binary search tree hooks and
1753 [classref boost::intrusive::sg_set sg_set]/
1754 [classref boost::intrusive::sg_multiset sg_multiset]
1755 containers:
1756
1757 [import ../example/doc_sg_set.cpp]
1758 [doc_sg_set_code]
1759
1760 [endsect]
1761
1762 [endsect]
1763
1764
1765 [section:treap_set_multiset Intrusive treap based associative containers: treap_set, treap_multiset and treap]
1766
1767 The name ['treap] is a mixture of ['tree] and ['heap] indicating that Treaps exhibit the properties of both
1768 binary search trees and heaps. A treap is a binary search tree that orders the nodes
1769 by a key but also by a priority attribute. The nodes are ordered so that the keys form a binary search tree and
1770 the priorities obey the max heap order property.
1771
1772 * If v is a left descendant of u, then key[v] < key[u];
1773 * If v is a right descendant of u, then key[v] > key[u];
1774 * If v is a child of u, then priority[v] <= priority[u];
1775
1776 If priorities are non-random, the tree will usually be unbalanced; this worse theoretical average-case
1777 behavior may be outweighed by better expected-case behavior, as the most important items will be near the root.
1778 This means most important objects will be retrieved faster than less important items and for items keys with equal keys
1779 most important objects will be found first. These properties are important for some applications.
1780
1781 The priority comparison will be provided just like the key comparison, via a function object that will be
1782 stored in the intrusive container. This means that the priority can be stored in the value to be introduced
1783 in the treap or computed on flight (via hashing or similar).
1784
1785 [*Boost.Intrusive] offers 3 containers based on treaps:
1786 [classref boost::intrusive::treap_set treap_set],
1787 [classref boost::intrusive::treap_multiset treap_multiset] and
1788 [classref boost::intrusive::treap treap]. The first two are similar to
1789 [classref boost::intrusive::set set] or
1790 [classref boost::intrusive::multiset multiset] and the latter is a generalization
1791 that offers functions both to insert unique and multiple keys.
1792
1793 The memory overhead of these containers with Boost.Intrusive hooks is 3
1794 pointers.
1795
1796 An empty, [classref boost::intrusive::treap_set treap_set],
1797 [classref boost::intrusive::treap_multiset treap_multiset] or
1798 [classref boost::intrusive::treap treap]
1799 has also the size of 3 pointers and an integer (supposing empty function objects for key and priority
1800 comparison and constant-time size).
1801
1802 [*Boost.Intrusive] treap associative containers don't use their own hook types but plain Binary search tree hooks.
1803 See [link intrusive.bst_hooks Binary search tree hooks: bs_set_base_hook and bs_set_member_hook] section for more
1804 information about these hooks.
1805
1806 [section:treap_set_multiset_containers treap_set, treap_multiset and treap containers]
1807
1808 [c++]
1809
1810    template <class T, class ...Options>
1811    class treap_set;
1812
1813    template <class T, class ...Options>
1814    class treap_multiset;
1815
1816    template <class T, class ...Options>
1817    class treap;
1818
1819 These containers receive the same options explained in the section
1820 [link intrusive.usage How to use Boost.Intrusive]:
1821
1822 *  [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
1823    [*`value_traits<class ValueTraits>`]: To specify the hook type or value traits used
1824    to configure the container. (To learn about value traits go to the section
1825    [link intrusive.value_traits Containers with custom ValueTraits].)
1826
1827 *  [*`constant_time_size<bool Enabled>`]: To activate the constant-time `size()` operation.
1828    Default: `constant_time_size<true>`
1829
1830 *  [*`size_type<typename SizeType>`]: To specify the type that will be used to store the size
1831    of the container. Default: `size_type<std::size_t>`
1832
1833 And they also can receive additional options:
1834
1835 *  [*`compare<class Compare>`]: Comparison function for the objects to be inserted
1836    in containers. The comparison functor must induce a strict weak ordering.
1837    Default: `compare< std::less<key_type> >`
1838
1839 *  [*`priority<class PriorityCompare>`]: Priority Comparison function for the objects to be inserted
1840    in containers. The comparison functor must induce a strict weak ordering.
1841    Default: `priority< priority_compare<key_type> >`
1842
1843 *  [*`key_of_value<class KeyOfValueFunctionObject>`]: A function object that will
1844    define the `key_type` of the value type to be stored. This type will allow a map-like interface. See
1845    [link intrusive.map_multimap Map and multimap-like interface with set and multiset]
1846    for details. Default: `key_type` is equal to `value_type` (set-like interface).
1847
1848 The default `priority_compare<T>` object function will call an unqualified function `priority_order`
1849 passing two constant `T` references as arguments and should return true if the first argument has
1850 higher priority (it will be searched faster), inducing strict weak ordering.
1851 The function will be found using ADL lookup so that
1852 the user just needs to define a `priority_order` function in the same namespace as the class:
1853
1854 [c++]
1855
1856    struct MyType
1857    {
1858       friend bool priority_order(const MyType &a, const MyType &b)
1859       {...}
1860    };
1861
1862 or
1863
1864    namespace mytype {
1865
1866    struct MyType{ ... };
1867
1868    bool priority_order(const MyType &a, const MyType &b)
1869    {...}
1870
1871    }  //namespace mytype {
1872
1873 [endsect]
1874
1875 [section:treap_set_exceptions Exception safety of treap-based intrusive containers]
1876
1877 In general, intrusive containers offer strong safety guarantees, but treap containers must deal
1878 with two possibly throwing functors (one for value ordering, another for priority ordering).
1879 Moreover, treap erasure operations require rotations based on the priority order function and
1880 this issue degrades usual `erase(const_iterator)` no-throw guarantee. However, intrusive offers
1881 the strongest possible behaviour in these situations. In summary:
1882
1883 *  If the priority order functor does not throw, treap-based containers, offer exactly the same
1884    guarantees as other tree-based containers.
1885
1886 *  If the priority order functor throws, treap-based containers offer strong guarantee.
1887
1888 [endsect]
1889
1890 [section:treap_set_multiset_example Example]
1891
1892 Now let's see a small example using binary search tree hooks and
1893 [classref boost::intrusive::treap_set treap_set]/
1894 [classref boost::intrusive::treap_multiset treap_multiset]
1895 containers:
1896
1897 [import ../example/doc_treap_set.cpp]
1898 [doc_treap_set_code]
1899
1900 [endsect]
1901
1902 [endsect]
1903
1904 [section:bst_hooks Binary search tree hooks: bs_set_base_hook and bs_set_member_hook]
1905
1906 Binary search tree hooks can be used with several tree-like containers that don't
1907 need any additional metadata for rebalancing operations. This has many advantages
1908 since binary search tree hooks can also be used to insert values in
1909 plain binary search tree, splay tree, scapegoat tree, and treap containers.
1910
1911 [c++]
1912
1913    template <class ...Options>
1914    class bs_set_base_hook;
1915
1916 *  [classref boost::intrusive::bs_set_base_hook bs_set_base_hook]:
1917    the user class derives publicly from this class to make
1918    it compatible with the mentioned tree based containers.
1919
1920 [c++]
1921
1922    template <class ...Options>
1923    class bs_set_member_hook;
1924
1925 *  [classref boost::intrusive::bs_set_member_hook bs_set_member_hook]:
1926    the user class contains a public member of this class to make
1927    it compatible with the mentioned tree based containers.
1928
1929 [classref boost::intrusive::bs_set_base_hook bs_set_base_hook] and
1930 [classref boost::intrusive::bs_set_member_hook bs_set_member_hook] receive
1931 the same options explained in the section
1932 [link intrusive.usage How to use Boost.Intrusive]:
1933
1934 *  [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
1935    so you can derive from more than one base hook.
1936    Default: `tag<default_tag>`.
1937
1938 *  [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
1939    Default: `link_mode<safe_link>`.
1940
1941 *  [*`void_pointer<class VoidPointer>`]: The pointer type to be used
1942    internally in the hook and propagated to the container.
1943    Default: `void_pointer<void*>`.
1944
1945 [endsect]
1946
1947 [section:advanced_lookups_insertions Advanced lookup and insertion functions for associative containers]
1948
1949 [section:advanced_lookups Advanced lookups]
1950
1951 [*Boost.Intrusive] associative containers offer an interface similar to STL associative
1952 containers. However, STL's ordered and unordered simple associative containers
1953 (`std::set`, `std::multiset`, `std::unordered_set` and `std::unordered_multiset`)
1954 have some inefficiencies caused by the interface in several search, insertion or erasure functions
1955 (`equal_range`, `lower_bound`, `upper_bound`, `find`, `insert`, `erase`...): the user can only operate
1956 with `value_type` objects or (starting from C++11),
1957 [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3657.htm heterogeneous comparison lookups]
1958 which are not flexible enough as `key_compare` shall support the comparison between the provided 
1959 key and `value_type`, which precludes the use of user-defined comparison objects that can partition the
1960 search in a compatible but advanced way.
1961
1962 To solve these problems, [*Boost.Intrusive] containers offers functions where a key type different
1963 from `key_type` and a comparison object are provided by the user. This applies to:
1964    *  equal_range
1965    *  lower_bound
1966    *  upper_bound
1967    *  count
1968    *  find
1969    *  erase
1970
1971 Requirements for such functions are:
1972
1973 * For unordered container the provided comparison and hashing
1974   function with the given key shall induce the same hash and equivalence as `key_compare` and `hasher`.
1975
1976 * For ordered associative containers, lookup and erasure functions, the container to be searched shall
1977   be partitioned in regards to the supplied comparison object and key. 
1978
1979 For more details, see  [*Requires] clauses of such functions in the reference.
1980
1981 [section:advanced_lookups_example Example]
1982
1983 Imagine that the object to be searched is quite expensive to construct (called `Expensive` in the example):
1984
1985 [import ../example/doc_assoc_optimized_code.cpp]
1986 [doc_assoc_optimized_code_normal_find]
1987
1988 If "key" c-string is quite long
1989 `Expensive` has to construct a `std::string` using heap memory. Like
1990 `Expensive`, many times the only member taking part in ordering issues is just
1991 a small part of the class. E.g.: with `Expensive`, only the internal
1992 `std::string` is needed to compare the object.
1993
1994 In both containers, if we call `get_from_set/get_from_unordered_set` in a loop, we might get a performance penalty,
1995 because we are forced to create a whole `Expensive` object to be able to find an
1996 equivalent one.
1997
1998 Sometimes the problem is not only performance-related, as
1999 we [*might not have enough information to construct the object] but we might
2000 [*have enough information to find the object]. In this case, a name is enough
2001 to search `Expensive` objects in the container but constructing an `Expensive`
2002 object might require more information that the searcher might not have.
2003
2004 To solve this, we can use the functions that take any type comparable with the value and a
2005 the 'compatible' comparison object (and hash, when the associative container is unordered)
2006 Let's see optimized search function:
2007
2008 [doc_assoc_optimized_code_optimized_find]
2009
2010 [endsect]
2011
2012 [endsect]
2013
2014 [section:advanced_insertions Advanced insertions]
2015
2016 A similar issue happens with insertions in simple ordered and unordered associative
2017 containers with unique keys (`std::set` and `std::unordered_set`). In these containers,
2018 if a value is already present, the value to be inserted is discarded. With expensive
2019 values, if the value is already present, we can suffer efficiency problems.
2020
2021 [classref boost::intrusive::set set] and [classref boost::intrusive::unordered_set unordered_set]-like
2022 containers have insertion functions (`insert_check`, `insert_unique_check`,...) to check efficiently, without
2023 constructing the value, if a value is present or not and if it's not present, a
2024 function to insert it immediately (`insert_commit`) without any further lookup. Requirements for functions
2025 that check the existence of such value are:
2026
2027 * For unordered container the provided comparison and hashing
2028   function with the given key shall induce the same hash and equivalence as `key_compare` and `hasher`.
2029
2030 * For ordered associative containers, the provided comparison function with the given key, shall induce the same
2031 strict weak order as `key_compare`.
2032
2033 To sum up, `insert_check` is similar to a normal `insert` but:
2034
2035 *  `insert_check` can be used with arbitrary keys
2036 *  if the insertion is possible (there is no equivalent value) `insert_check` collects all the needed information
2037 in an `insert_commit_data` structure, so that `insert_commit`:
2038    *   [*does not execute] further comparisons
2039    *   can be executed with [*constant-time complexity]
2040    *   has [*no-throw guarantee].
2041
2042 These functions must be used with care, 
2043 no other insertion or erasure must be executed between an `insert_check` and an `insert_commit`
2044 pair. Otherwise, the behaviour is undefined.
2045
2046 See [classref boost::intrusive::set set]
2047 and [classref boost::intrusive::unordered_set unordered_set]-like containers' reference
2048 for more information about `insert_check` and `insert_commit`.
2049
2050 With multiple ordered and unordered associative containers
2051 ([classref boost::intrusive::multiset multiset] and
2052 [classref boost::intrusive::unordered_multiset unordered_multiset]) there  is
2053 no need for these advanced insertion functions, since insertions are always successful.
2054
2055 [section:advanced_insertions_example Example]
2056
2057 For example, using the same `Expensive` class,
2058 this function can be inefficient:
2059
2060 [doc_assoc_optimized_code_normal_insert]
2061
2062 If the object is already present, we are constructing an `Expensive` that
2063 will be discarded, and this is a waste of resources. Instead of that, let's use
2064 `insert_check` and `insert_commit` functions:
2065
2066 [doc_assoc_optimized_code_optimized_insert]
2067
2068 [endsect]
2069
2070 [endsect]
2071
2072 [section:positional_insertions Positional insertions]
2073
2074 Some ordered associative containers offer low-level functions to bypass ordering
2075 checks and insert nodes directly in desired tree positions. These functions are
2076 provided for performance reasons when values to be inserted in the container are
2077 known to fulfill order (sets and multisets) and uniqueness (sets) invariants. A
2078 typical usage of these functions is when intrusive associative containers are used
2079 to build non-intrusive containers and the programmer wants to speed up assignments
2080 from other associative containers: if the ordering and uniqueness properties are the same,
2081 there is no need to waste time checking the position of each source value, because values
2082 are already ordered: back insertions will be much more efficient.
2083
2084 [*Note:] These functions [*don't check preconditions] so they must used with care. They
2085 are low-level operations that [*will break container invariants if
2086 ordering and uniqueness preconditions are not assured by the caller.]
2087
2088 Let's see an example:
2089
2090 [import ../example/doc_positional_insertion.cpp]
2091 [doc_positional_insertion]
2092
2093 [endsect]
2094
2095 For more information about advanced lookup and insertion functions see
2096 associative containers' documentation (e.g.
2097 [classref boost::intrusive::set set],
2098 [classref boost::intrusive::multiset multiset],
2099 [classref boost::intrusive::unordered_set unordered_set] and
2100 [classref boost::intrusive::unordered_multiset unordered_multiset] references).
2101
2102 [endsect]
2103
2104 [section:erasing_and_disposing Erasing and disposing values from Boost.Intrusive containers]
2105
2106 One of the most tedious tasks when using intrusive containers is the management of the erased elements.
2107 When using STL containers, the container itself unlinks and destroys the contained elements, but with
2108 intrusive containers, the user must explicitly destroy the object after erasing an element from the container.
2109 This makes STL-like functions erasing multiple objects unhelpful: the user can't destroy every erased element.
2110 For example, let's take the function `remove_if` from [classref boost::intrusive::list list]:
2111
2112 [c++]
2113
2114    template<class Pred>
2115    void remove_if(Pred pred);
2116
2117 How can the user destroy the elements (say, using `operator delete`) that will be erased according
2118 to the predicate? [*Boost.Intrusive] containers offer additional functions that take a function
2119 object that will be called after the element has been erased from the container. For example,
2120 [classref boost::intrusive::list list] offers:
2121
2122 [c++]
2123
2124    template<class Pred, class Disposer>
2125    void remove_and_dispose_if(Pred pred, Disposer disposer)
2126
2127 With this function the user can efficiently remove and destroy elements if the disposer
2128 function destroys an object: `remove_and_dispose_if`
2129 will call the "disposer" function object for every removed element. [classref boost::intrusive::list list] offers
2130 more functions taking a disposer function object as argument, like `erase_and_dispose`, `clear_and_dispose`,
2131 `remove_and_dispose`, etc.
2132
2133 Note that the disposing function does not need to just destroy the object. It can
2134 implement any other operation like inserting the remove object in another container.
2135 Let's see a small example:
2136
2137 [import ../example/doc_erasing_and_disposing.cpp]
2138 [doc_erasing_and_disposing]
2139
2140 All [*Boost.Intrusive] containers offer these "erase + dispose" additional members for all functions
2141 that erase an element from the container.
2142
2143
2144
2145 [endsect]
2146
2147 [section:clone_from Cloning Boost.Intrusive containers]
2148
2149 As previously mentioned, [*Boost.Intrusive] containers are [*non-copyable and non-assignable], because
2150 intrusive containers don't allocate memory at all. To implement a copy-constructor or assignment operator,
2151 the user must clone one by one all the elements of the container and insert them in another intrusive container.
2152 However, cloning by hand is usually more inefficient than a member cloning function and a specialized cloning
2153 function can offer more guarantees than the manual cloning (better exception safety guarantees, for example).
2154
2155 To ease the implementation of copy constructors and assignment operators of classes containing [*Boost.Intrusive]
2156 containers, all [*Boost.Intrusive] containers offer a special cloning function called `clone_from`.
2157
2158 Apart from the container to be cloned, `clone_from` takes two function objects as arguments. For example, consider the
2159 `clone_from` member function of [classref boost::intrusive::list list]:
2160
2161 [c++]
2162
2163    template <class Cloner, class Disposer>
2164    void clone_from(const list &src, Cloner cloner, Disposer disposer);
2165
2166 This function will make `*this` a clone of `src`. Let's explain the arguments:
2167
2168 *   The first parameter is the list to be cloned.
2169 *   The second parameter is a function object that will clone `value_type` objects and
2170    return a pointer to the clone. It must implement the following function:
2171    `pointer operator()(const value_type &)`.
2172 *   The second parameter is a function object that will dispose `value_type` objects. It's used first
2173    to empty the container before cloning and to dispose the elements if an exception is thrown.
2174
2175 The cloning function works as follows:
2176
2177 *   First it clears and disposes all the elements from *this using the disposer function object.
2178 *   After that it starts cloning all the elements of the source container using the cloner function object.
2179 *   If any operation in the cloning function (for example, the cloner function object) throws,
2180    all the constructed elements are disposed using the disposer function object.
2181
2182
2183 Here is an example of `clone_from`:
2184
2185 [import ../example/doc_clone_from.cpp]
2186 [doc_clone_from]
2187
2188 [endsect]
2189
2190 [section:function_hooks Using function hooks]
2191
2192 A programmer might find that base or member hooks are not flexible enough in some situations.
2193 In some applications it would be optimal to put a hook deep inside a member of a class or just outside the class.
2194 [*Boost.Intrusive] has an easy option to allow such cases: [classref boost::intrusive::function_hook function_hook].
2195
2196 This option is similar to [classref boost::intrusive::member_hook member_hook] or
2197 [classref boost::intrusive::base_hook base_hook], but the programmer can specify a function
2198 object that tells the container how to obtain a hook from a value and vice versa.
2199 The programmer just needs to define the following function object:
2200
2201 [c++]
2202
2203    //This functor converts between value_type and a hook_type
2204    struct Functor
2205    {
2206       //Required types
2207       typedef /*impl-defined*/      hook_type;
2208       typedef /*impl-defined*/      hook_ptr;
2209       typedef /*impl-defined*/      const_hook_ptr;
2210       typedef /*impl-defined*/      value_type;
2211       typedef /*impl-defined*/      pointer;
2212       typedef /*impl-defined*/      const_pointer;
2213       //Required static functions
2214       static hook_ptr to_hook_ptr (value_type &value);
2215       static const_hook_ptr to_hook_ptr(const value_type &value);
2216       static pointer to_value_ptr(hook_ptr n);
2217       static const_pointer to_value_ptr(const_hook_ptr n);
2218    };
2219
2220 Converting from values to hooks is generally easy, since most hooks are
2221 in practice members or base classes of class data members. The inverse operation
2222 is a bit more complicated, but [*Boost.Intrusive] offers a bit of help with the function
2223 [funcref boost::intrusive::get_parent_from_member get_parent_from_member],
2224 which allows easy conversions from the address of a data member to the address of
2225 the parent holding that member. Let's see a little example of
2226 [classref boost::intrusive::function_hook function_hook]:
2227
2228 [import ../example/doc_function_hooks.cpp]
2229 [doc_function_hooks]
2230
2231 [endsect]
2232
2233
2234 [section:recursive Recursive Boost.Intrusive containers]
2235
2236 [*Boost.Intrusive] containers can be used to define recursive structures very easily,
2237 allowing complex data structures with very low overhead. Let's see an example:
2238
2239 [import ../example/doc_recursive.cpp]
2240 [doc_recursive]
2241
2242 Recursive data structures using [*Boost.Intrusive] containers must avoid using hook deduction to avoid early type
2243 instantiation:
2244
2245 [c++]
2246
2247   //This leads to compilation error (Recursive is instantiated by
2248   //'list' to deduce hook properties (pointer type, tag, safe-mode...)
2249   class Recursive
2250   {  //...
2251
2252      list< Recursive > l;
2253      //...
2254   };
2255
2256   //Ok, programmer must specify the hook type to avoid early Recursive instantiation
2257   class Recursive
2258   {  //...
2259      list< Recursive, base_hook<BaseHook> > l;
2260      //...
2261   };
2262
2263
2264 Member hooks are not suitable for recursive structures:
2265
2266 [c++]
2267
2268    class Recursive
2269    {
2270       private:
2271       Recursive(const Recursive&);
2272       Recursive & operator=(const Recursive&);
2273
2274       public:
2275       list_member_hook<> memhook;
2276       list< Recursive, member_hook<Recursive, list_member_hook<>, &Recursive::memhook> > children;
2277    };
2278
2279 Specifying `&Recursive::memhook` (that is, the offset between memhook and Recursive) provokes an early
2280 instantiation of `Recursive`. To define recursive structures using member hooks, a programmer should use
2281 [classref ::boost::interprocess::function_hook function_hook]:
2282
2283 [import ../example/doc_recursive_member.cpp]
2284 [doc_recursive_member]
2285
2286 [endsect]
2287
2288
2289 [section:using_smart_pointers Using smart pointers with Boost.Intrusive containers]
2290
2291 [*Boost.Intrusive] hooks can be configured to use other pointers than raw pointers.
2292 When a [*Boost.Intrusive] hook is configured with a smart pointer as an argument,
2293 this pointer configuration is passed to the containers. For example, if the following
2294 hook is configured with a smart pointer (for example, an offset pointer from
2295 [*Boost.Interprocess]):
2296
2297 [import ../example/doc_offset_ptr.cpp]
2298 [doc_offset_ptr_0]
2299
2300 Any intrusive list constructed using this hook will be ready for shared memory,
2301 because the intrusive list will also use offset pointers internally. For example,
2302 we can create an intrusive list in shared memory combining [*Boost.Interprocess]
2303 and [*Boost.Intrusive]:
2304
2305 [doc_offset_ptr_1]
2306
2307 [section:smart_pointers_requirements Requirements for smart pointers compatible with Boost.Intrusive]
2308
2309 Not every smart pointer is compatible with [*Boost.Intrusive]:
2310
2311 * It must be compatible with C++11 [@http://en.cppreference.com/w/cpp/memory/pointer_traits `std::pointer_traits`]
2312    requirements. [*Boost.Intrusive] uses its own [classref boost::intrusive::pointer_traits pointer_traits]
2313    class to implement those features in both C++11 and C++03 compilers.
2314 * It must  have the same ownership semantics as a raw pointer. This means that
2315    resource management smart pointers (like `boost::shared_ptr`) can't be used.
2316
2317 The conversion from the smart pointer to a raw pointer will be implemented as a recursive call to
2318 `operator->()` until the function returns a raw pointer.
2319
2320 [endsect]
2321
2322 [endsect]
2323
2324 [section:obtaining_iterators_from_values Obtaining iterators from values]
2325
2326 [*Boost.Intrusive] offers another useful feature that's not present in STL
2327 containers: it's possible to obtain an iterator to a value from the value itself.
2328 This feature is implemented in [*Boost.Intrusive] containers by a
2329 function called `iterator_to`:
2330
2331 [c++]
2332
2333    iterator iterator_to(reference value);
2334    const_iterator iterator_to(const_reference value);
2335
2336 For [*Boost.Intrusive] containers that have local iterators, like unordered
2337 associative containers, we can also obtain local iterators:
2338
2339 [c++]
2340
2341    local_iterator local_iterator_to(reference value);
2342    const_local_iterator local_iterator_to(const_reference value) const;
2343
2344 For most [*Boost.Intrusive] containers
2345 ([classref boost::intrusive::list list],
2346 [classref boost::intrusive::slist slist],
2347 [classref boost::intrusive::set set],
2348 [classref boost::intrusive::multiset multiset]) we have an alternative
2349 static `s_iterator_to` function.
2350
2351 For unordered associative containers
2352 ([classref boost::intrusive::unordered_set unordered_set],
2353 [classref boost::intrusive::multiset multiset]),
2354 `iterator_to` has no static alternative function.
2355 On the other hand, `local_iterator_to` functions
2356 have their `s_local_iterator_to` static alternatives.
2357
2358 Alternative static functions are available under certain circumstances
2359 explained in the [link intrusive.value_traits.stateful_value_traits Stateful value traits] section;
2360 if the programmer uses hooks provided by [*Boost.Intrusive], those functions
2361 will be available.
2362
2363 Let's see a small function that shows the use of `iterator_to` and
2364 `local_iterator_to`:
2365
2366 [import ../example/doc_iterator_from_value.cpp]
2367 [doc_iterator_from_value]
2368
2369 [endsect]
2370
2371 [section:any_hooks Any Hooks: A single hook for any Intrusive container]
2372
2373 Sometimes, a class programmer wants to place a class in several intrusive
2374 containers but no at the same time. In this case, the programmer might
2375 decide to insert two hooks in the same class.
2376
2377 [c++]
2378
2379    class MyClass
2380       : public list_base_hook<>, public slist_base_hook<> //...
2381    {};
2382
2383 However, there is a more size-efficient alternative in [*Boost.Intrusive]: "any" hooks
2384 ([classref boost::intrusive::any_base_hook any_base_hook] and
2385 [classref boost::intrusive::any_member_hook any_member_hook]).
2386 These hooks can be used to store a type in several containers
2387 offered by [*Boost.Intrusive] minimizing the size of the class.
2388
2389 These hooks support these options:
2390
2391 *  [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
2392    so you can derive from more than one slist hook.
2393    Default: `tag<default_tag>`.
2394
2395 *  [*`link_mode<link_mode_type LinkMode>`]: The linking policy.
2396    `link_mode<auto_unlink>` is [*not] supported and `link_mode<safe_mode>`
2397    might offer weaker error detection in any hooks than in other hooks.
2398    Default: `link_mode<safe_link>`.
2399
2400 *  [*`void_pointer<class VoidPointer>`]: The pointer type to be used
2401    internally in the hook and propagated to the container.
2402    Default: `void_pointer<void*>`.
2403
2404 `auto_unlink` can't be supported because the hook does not know in which type of
2405 container might be currently inserted. Additionally, these hooks don't support `unlink()` and
2406 `swap_nodes()` operations for the same reason.
2407
2408 Here is an example that creates a class with two any hooks, and uses one to insert the
2409 class in a [classref slist] and the other one in a [classref list].
2410
2411 [import ../example/doc_any_hook.cpp]
2412 [doc_any_hook]
2413
2414 [endsect]
2415
2416 [section:concepts Concepts explained]
2417
2418 This section will expand the explanation of previously presented basic concepts
2419 before explaining the customization options of [*Boost.Intrusive].
2420
2421 *  [*Node Algorithms]: A set of static functions that implement basic operations
2422    on a group of nodes: initialize a node, link_mode_type a node to a group of nodes,
2423    unlink a node from another group of nodes, etc. For example, a circular
2424    singly linked list is a group of nodes, where each node has a pointer to the
2425    next node. [*Node Algorithms] just require a [*NodeTraits]
2426    template parameter and they can work with any [*NodeTraits] class that fulfills
2427    the needed interface. As an example, here is a class that implements operations
2428    to manage a group of nodes forming a circular singly linked list:
2429
2430 [c++]
2431
2432    template<class NodeTraits>
2433    struct my_slist_algorithms
2434    {
2435       typedef typename NodeTraits::node_ptr       node_ptr;
2436       typedef typename NodeTraits::const_node_ptr const_node_ptr;
2437
2438       //Get the previous node of "this_node"
2439       static node_ptr get_prev_node(node_ptr this_node)
2440       {
2441          node_ptr p = this_node;
2442          while (this_node != NodeTraits::get_next(p))
2443             p = NodeTraits::get_next(p);
2444          return p;
2445       }
2446
2447       // number of elements in the group of nodes containing "this_node"
2448       static std::size_t count(const_node_ptr this_node)
2449       {
2450          std::size_t result = 0;
2451          const_node_ptr p = this_node;
2452          do{
2453             p = NodeTraits::get_next(p);
2454             ++result;
2455          } while (p != this_node);
2456          return result;
2457       }
2458
2459       // More operations
2460       // ...
2461    };
2462
2463 *  [*Node Traits]: A class that encapsulates the basic information and
2464    operations on a node within a group of nodes:
2465    the type of the node, a function to obtain the pointer to the next node, etc.
2466    [*Node Traits] specify the configuration information [*Node Algorithms]
2467    need. Each type of [*Node Algorithm] expects an interface that compatible
2468    [*Node Traits] classes must implement.
2469    As an example, this is the definition of a [*Node Traits] class that
2470    is compatible with the previously presented `my_slist_algorithms`:
2471
2472 [c++]
2473
2474    struct my_slist_node_traits
2475    {
2476       //The type of the node
2477       struct node
2478       {
2479          node *next_;
2480       };
2481
2482       typedef node *       node_ptr;
2483       typedef const node * const_node_ptr;
2484
2485       //A function to obtain a pointer to the next node
2486       static node_ptr get_next(const_node_ptr n)
2487       {  return n->next_;  }
2488
2489       //A function to set the pointer to the next node
2490       static void set_next(node_ptr n, node_ptr next)
2491       {  n->next_ = next;  }
2492    };
2493
2494
2495 *  [*Hook]: A class that the user must add as a base class or as a member to his own
2496    class to make that class insertable in an intrusive container. Usually the hook
2497    contains a node object that will be used to form the group of nodes:
2498    For example, the following class is a [*Hook] that the user can add as a base class,
2499    to make the user class compatible with a singly linked list container:
2500
2501 [c++]
2502
2503    class my_slist_base_hook
2504          //This hook contains a node, that will be used
2505          //to link the user object in the group of nodes
2506       : private my_slist_node_traits::node
2507    {
2508       typedef my_slist_node_traits::node_ptr       node_ptr;
2509       typedef my_slist_node_traits::const_node_ptr const_node_ptr;
2510
2511       //Converts the generic node to the hook
2512       static my_slist_base_hook *to_hook_ptr(node_ptr p)
2513       {  return static_cast<my_slist_base_hook*>(p); }
2514
2515       //Returns the generic node stored by this hook
2516       node_ptr to_node_ptr()
2517       { return static_cast<node *const>(this); }
2518
2519       // More operations
2520       // ...
2521    };
2522
2523    //To make MyClass compatible with an intrusive singly linked list
2524    //derive our class from the hook.
2525    class MyClass
2526       :  public my_slist_base_hook
2527    {
2528       void set(int value);
2529       int get() const;
2530
2531       private:
2532       int value_;
2533    };
2534
2535 *  [*Intrusive Container]: A container that offers a STL-like interface to store
2536    user objects. An intrusive container can be templatized to store different
2537    value types that use different hooks. An intrusive container is also more elaborate
2538    than a group of nodes: it can store the number of elements to achieve constant-time
2539    size information, it can offer debugging facilities, etc.
2540    For example, an [classref boost::intrusive::slist slist] container
2541    (intrusive singly linked list) should
2542    be able to hold `MyClass` objects that might have decided to store the hook
2543    as a base class or as a member. Internally, the container will use [*Node Algorithms]
2544    to implement its operations, and an intrusive container is configured using
2545    a template parameter called [*ValueTraits]. [*ValueTraits] will contain
2546    the information to convert user classes in nodes compatible with [*Node Algorithms].
2547    For example, this a possible [classref boost::intrusive::slist slist] implementation:
2548
2549 [c++]
2550
2551    template<class ValueTraits, ...>
2552    class slist
2553    {
2554       public:
2555       typedef typename ValueTraits::value_type value_type;
2556
2557       //More typedefs and functions
2558       // ...
2559
2560       //Insert the value as the first element of the list
2561       void push_front (reference value)
2562       {
2563          node_ptr to_insert(ValueTraits::to_node_ptr(value));
2564          circular_list_algorithms::link_after(to_insert, get_root_node());
2565       }
2566
2567       // More operations
2568       // ...
2569    };
2570
2571 *  [*Semi-Intrusive Container]: A semi-intrusive container is similar to an
2572    intrusive container, but apart from the values to be inserted in the container,
2573    it needs additional memory (for example, auxiliary arrays or indexes).
2574
2575 *  [*Value Traits]: As we can see, to make our classes intrusive-friendly we add
2576    a simple hook as a member or base class. The hook contains a generic node
2577    that will be inserted in a group of nodes. [*Node Algorithms] just work
2578    with nodes and don't know anything about user classes. On the other
2579    hand, an intrusive container needs to know how to obtain a node from a user class,
2580    and also the inverse operation.
2581    So we can define [*ValueTraits] as the glue between user classes and nodes
2582    required by [*Node Algorithms].
2583    Let's see a possible implementation of a value traits class that glues MyClass
2584    and the node stored in the hook:
2585
2586 [c++]
2587
2588    struct my_slist_derivation_value_traits
2589    {
2590       public:
2591       typedef slist_node_traits           node_traits;
2592       typedef MyClass                     value_type;
2593       typedef node_traits::node_ptr       node_ptr;
2594       typedef value_type*                 pointer;
2595       //...
2596
2597       //Converts user's value to a generic node
2598       static node_ptr to_node_ptr(reference value)
2599       { return static_cast<slist_base_hook &>(value).to_node_ptr(); }
2600
2601       //Converts a generic node into user's value
2602       static value_type *to_value_ptr(node_traits::node *n)
2603       { static_cast<value_type*>(slist_base_hook::to_hook_ptr(n)); }
2604
2605       // More operations
2606       // ...
2607    };
2608
2609 [endsect]
2610
2611 [section:node_algorithms Node algorithms with custom NodeTraits]
2612
2613 As explained in the [link intrusive.concepts Concepts] section, [*Boost.Intrusive]
2614 containers are implemented using node algorithms that work on generic nodes.
2615
2616 Sometimes, the use of intrusive containers is expensive for some environments
2617 and the programmer might want to avoid all the template instantiations
2618 related to [*Boost.Intrusive] containers. However, the user can still benefit
2619 from [*Boost.Intrusive] using the node algorithms, because some of those algorithms,
2620 like red-black tree algorithms, are not trivial to write.
2621
2622 All node algorithm classes are
2623 templatized by a `NodeTraits` class. This class encapsulates the needed internal
2624 type declarations and operations to make a node compatible with node algorithms.
2625 Each type of node algorithms has its own requirements:
2626
2627 [section:circular_slist_algorithms Intrusive singly linked list algorithms]
2628
2629 These algorithms are static
2630 members of the [classref boost::intrusive::circular_slist_algorithms circular_slist_algorithms] class:
2631
2632 [c++]
2633
2634    template<class NodeTraits>
2635    struct circular_slist_algorithms;
2636
2637 An empty list is formed by a node whose pointer to the next node points
2638 to itself. [classref boost::intrusive::circular_slist_algorithms circular_slist_algorithms]
2639 is configured with a NodeTraits class, which encapsulates
2640 the information about the node to be manipulated. NodeTraits must support the
2641 following interface:
2642
2643 [*Typedefs]:
2644
2645 *  `node`: The type of the node that forms the circular list
2646
2647 *  `node_ptr`: The type of a pointer to a node (usually node*)
2648
2649 *  `const_node_ptr`: The type of a pointer to a const node (usually const node*)
2650
2651 [*Static functions]:
2652
2653 *  `static node_ptr get_next(const_node_ptr n);`:
2654    Returns a pointer to the next node stored in "n".
2655
2656 *  `static void set_next(node_ptr n, node_ptr next);`:
2657    Sets the pointer to the next node stored in "n" to "next".
2658
2659 Once we have a node traits configuration we can use [*Boost.Intrusive] algorithms
2660 with our nodes:
2661
2662 [import ../example/doc_slist_algorithms.cpp]
2663 [doc_slist_algorithms_code]
2664
2665 For a complete list of functions see
2666 [classref boost::intrusive::circular_slist_algorithms circular_slist_algorithms reference].
2667
2668 [endsect]
2669
2670 [section:circular_list_algorithms Intrusive doubly linked list algorithms]
2671
2672 These algorithms are static
2673 members of the [classref boost::intrusive::circular_list_algorithms circular_list_algorithms] class:
2674
2675 [c++]
2676
2677    template<class NodeTraits>
2678    struct circular_list_algorithms;
2679
2680 An empty list is formed by a node whose pointer to the next node points
2681 to itself. [classref boost::intrusive::circular_list_algorithms circular_list_algorithms]
2682 is configured with a NodeTraits class, which encapsulates
2683 the information about the node to be manipulated. NodeTraits must support the
2684 following interface:
2685
2686 [*Typedefs]:
2687
2688 *  `node`: The type of the node that forms the circular list
2689
2690 *  `node_ptr`: The type of a pointer to a node (usually node*)
2691
2692 *  `const_node_ptr`: The type of a pointer to a const node (usually const node*)
2693
2694 [*Static functions]:
2695
2696 *  `static node_ptr get_next(const_node_ptr n);`:
2697    Returns a pointer to the next node stored in "n".
2698
2699 *  `static void set_next(node_ptr n, node_ptr next);`:
2700    Sets the pointer to the next node stored in "n" to "next".
2701
2702 *  `static node_ptr get_previous(const_node_ptr n);`:
2703    Returns a pointer to the previous node stored in "n".
2704
2705 *  `static void set_previous(node_ptr n, node_ptr prev);`:
2706    Sets the pointer to the previous node stored in "n" to "prev".
2707
2708 Once we have a node traits configuration we can use [*Boost.Intrusive] algorithms
2709 with our nodes:
2710
2711 [import ../example/doc_list_algorithms.cpp]
2712 [doc_list_algorithms_code]
2713
2714 For a complete list of functions see
2715 [classref boost::intrusive::circular_list_algorithms circular_list_algorithms reference].
2716
2717 [endsect]
2718
2719 [section:rbtree_algorithms Intrusive red-black tree algorithms]
2720
2721 These algorithms are static
2722 members of the [classref boost::intrusive::rbtree_algorithms rbtree_algorithms] class:
2723
2724 [c++]
2725
2726    template<class NodeTraits>
2727    struct rbtree_algorithms;
2728
2729
2730 An empty tree is formed by a node whose pointer to the parent node is null,
2731 the left and right node pointers point to itself, and whose color is red.
2732 [classref boost::intrusive::rbtree_algorithms rbtree_algorithms]
2733 is configured with a NodeTraits class, which encapsulates
2734 the information about the node to be manipulated. NodeTraits must support the
2735 following interface:
2736
2737 [*Typedefs]:
2738
2739 *  `node`: The type of the node that forms the circular rbtree
2740
2741 *  `node_ptr`: The type of a pointer to a node (usually node*)
2742
2743 *  `const_node_ptr`: The type of a pointer to a const node (usually const node*)
2744
2745 *  `color`: The type that can store the color of a node
2746
2747 [*Static functions]:
2748
2749 *  `static node_ptr get_parent(const_node_ptr n);`:
2750    Returns a pointer to the parent node stored in "n".
2751
2752 *  `static void set_parent(node_ptr n, node_ptr p);`:
2753    Sets the pointer to the parent node stored in "n" to "p".
2754
2755 *  `static node_ptr get_left(const_node_ptr n);`:
2756    Returns a pointer to the left node stored in "n".
2757
2758 *  `static void set_left(node_ptr n, node_ptr l);`:
2759    Sets the pointer to the left node stored in "n" to "l".
2760
2761 *  `static node_ptr get_right(const_node_ptr n);`:
2762    Returns a pointer to the right node stored in "n".
2763
2764 *  `static void set_right(node_ptr n, node_ptr r);`:
2765    Sets the pointer to the right node stored in "n" to "r".
2766
2767 *  `static color get_color(const_node_ptr n);`:
2768    Returns the color stored in "n".
2769
2770 *  `static void set_color(node_ptr n, color c);`:
2771    Sets the color stored in "n" to "c".
2772
2773 *  `static color black();`:
2774    Returns a value representing the black color.
2775
2776 *  `static color red();`:
2777    Returns a value representing the red color.
2778
2779 Once we have a node traits configuration we can use [*Boost.Intrusive] algorithms
2780 with our nodes:
2781
2782 [import ../example/doc_rbtree_algorithms.cpp]
2783 [doc_rbtree_algorithms_code]
2784
2785 For a complete list of functions see
2786 [classref boost::intrusive::rbtree_algorithms rbtree_algorithms reference].
2787
2788 [endsect]
2789
2790 [section:splaytree_algorithms Intrusive splay tree algorithms]
2791
2792 These algorithms are static
2793 members of the [classref boost::intrusive::splaytree_algorithms splaytree_algorithms] class:
2794
2795 [c++]
2796
2797    template<class NodeTraits>
2798    struct splaytree_algorithms;
2799
2800
2801 An empty tree is formed by a node whose pointer to the parent node is null,
2802 and whose left and right nodes pointers point to itself.
2803 [classref boost::intrusive::splaytree_algorithms splaytree_algorithms]
2804 is configured with a NodeTraits class, which encapsulates
2805 the information about the node to be manipulated. NodeTraits must support the
2806 following interface:
2807
2808 [*Typedefs]:
2809
2810 *  `node`: The type of the node that forms the circular splaytree
2811
2812 *  `node_ptr`: The type of a pointer to a node (usually node*)
2813
2814 *  `const_node_ptr`: The type of a pointer to a const node (usually const node*)
2815
2816 [*Static functions]:
2817
2818 *  `static node_ptr get_parent(const_node_ptr n);`:
2819    Returns a pointer to the parent node stored in "n".
2820
2821 *  `static void set_parent(node_ptr n, node_ptr p);`:
2822    Sets the pointer to the parent node stored in "n" to "p".
2823
2824 *  `static node_ptr get_left(const_node_ptr n);`:
2825    Returns a pointer to the left node stored in "n".
2826
2827 *  `static void set_left(node_ptr n, node_ptr l);`:
2828    Sets the pointer to the left node stored in "n" to "l".
2829
2830 *  `static node_ptr get_right(const_node_ptr n);`:
2831    Returns a pointer to the right node stored in "n".
2832
2833 *  `static void set_right(node_ptr n, node_ptr r);`:
2834    Sets the pointer to the right node stored in "n" to "r".
2835
2836 Once we have a node traits configuration we can use [*Boost.Intrusive] algorithms
2837 with our nodes:
2838
2839 [import ../example/doc_splaytree_algorithms.cpp]
2840 [doc_splaytree_algorithms_code]
2841
2842 For a complete list of functions see
2843 [classref boost::intrusive::splaytree_algorithms splaytree_algorithms reference].
2844
2845 [endsect]
2846
2847 [section:avltree_algorithms Intrusive avl tree algorithms]
2848
2849 [classref boost::intrusive::avltree_algorithms avltree_algorithms] have the same
2850 interface as [classref boost::intrusive::rbtree_algorithms rbtree_algorithms].
2851
2852 [c++]
2853
2854    template<class NodeTraits>
2855    struct avltree_algorithms;
2856
2857 [classref boost::intrusive::avltree_algorithms avltree_algorithms]
2858 is configured with a NodeTraits class, which encapsulates
2859 the information about the node to be manipulated. NodeTraits must support the
2860 following interface:
2861
2862 [*Typedefs]:
2863
2864 *  `node`: The type of the node that forms the circular avltree
2865
2866 *  `node_ptr`: The type of a pointer to a node (usually node*)
2867
2868 *  `const_node_ptr`: The type of a pointer to a const node (usually const node*)
2869
2870 *  `balance`: A type that can represent 3 balance types (usually an integer)
2871
2872 [*Static functions]:
2873
2874 *  `static node_ptr get_parent(const_node_ptr n);`:
2875    Returns a pointer to the parent node stored in "n".
2876
2877 *  `static void set_parent(node_ptr n, node_ptr p);`:
2878    Sets the pointer to the parent node stored in "n" to "p".
2879
2880 *  `static node_ptr get_left(const_node_ptr n);`:
2881    Returns a pointer to the left node stored in "n".
2882
2883 *  `static void set_left(node_ptr n, node_ptr l);`:
2884    Sets the pointer to the left node stored in "n" to "l".
2885
2886 *  `static node_ptr get_right(const_node_ptr n);`:
2887    Returns a pointer to the right node stored in "n".
2888
2889 *  `static void set_right(node_ptr n, node_ptr r);`:
2890    Sets the pointer to the right node stored in "n" to "r".
2891
2892 *  `static balance get_balance(const_node_ptr n);`:
2893    Returns the balance factor stored in "n".
2894
2895 *  `static void set_balance(node_ptr n, balance b);`:
2896    Sets the balance factor stored in "n" to "b".
2897
2898 *  `static balance negative();`:
2899    Returns a value representing a negative balance factor.
2900
2901 *  `static balance zero();`:
2902    Returns a value representing a zero balance factor.
2903
2904 *  `static balance positive();`:
2905    Returns a value representing a positive balance factor.
2906
2907 Once we have a node traits configuration we can use [*Boost.Intrusive] algorithms
2908 with our nodes:
2909
2910 [import ../example/doc_avltree_algorithms.cpp]
2911 [doc_avltree_algorithms_code]
2912
2913 For a complete list of functions see
2914 [classref boost::intrusive::avltree_algorithms avltree_algorithms reference].
2915
2916 [endsect]
2917
2918
2919 [section:treap_algorithms Intrusive treap algorithms]
2920
2921 [classref boost::intrusive::treap_algorithms treap_algorithms] have the same
2922 interface as [classref boost::intrusive::rbtree_algorithms rbtree_algorithms].
2923
2924 [c++]
2925
2926    template<class NodeTraits>
2927    struct treap_algorithms;
2928
2929 [classref boost::intrusive::treap_algorithms treap_algorithms]
2930 is configured with a NodeTraits class, which encapsulates
2931 the information about the node to be manipulated. NodeTraits must support the
2932 following interface:
2933
2934 [*Typedefs]:
2935
2936 *  `node`: The type of the node that forms the circular treap
2937
2938 *  `node_ptr`: The type of a pointer to a node (usually node*)
2939
2940 *  `const_node_ptr`: The type of a pointer to a const node (usually const node*)
2941
2942 [*Static functions]:
2943
2944 *  `static node_ptr get_parent(const_node_ptr n);`:
2945    Returns a pointer to the parent node stored in "n".
2946
2947 *  `static void set_parent(node_ptr n, node_ptr p);`:
2948    Sets the pointer to the parent node stored in "n" to "p".
2949
2950 *  `static node_ptr get_left(const_node_ptr n);`:
2951    Returns a pointer to the left node stored in "n".
2952
2953 *  `static void set_left(node_ptr n, node_ptr l);`:
2954    Sets the pointer to the left node stored in "n" to "l".
2955
2956 *  `static node_ptr get_right(const_node_ptr n);`:
2957    Returns a pointer to the right node stored in "n".
2958
2959 *  `static void set_right(node_ptr n, node_ptr r);`:
2960    Sets the pointer to the right node stored in "n" to "r".
2961
2962 Once we have a node traits configuration we can use [*Boost.Intrusive] algorithms
2963 with our nodes:
2964
2965 [import ../example/doc_treap_algorithms.cpp]
2966 [doc_treap_algorithms_code]
2967
2968 For a complete list of functions see
2969 [classref boost::intrusive::treap_algorithms treap_algorithms reference].
2970
2971 [endsect]
2972
2973
2974 [/
2975 /
2976 /[section:sgtree_algorithms Intrusive sg tree algorithms]
2977 /
2978 /
2979 /[classref boost::intrusive::sgtree_algorithms sgtree_algorithms] have the same
2980 /interface as [classref boost::intrusive::rbtree_algorithms rbtree_algorithms].
2981 /
2982 /[c++]
2983 /
2984 /   template<class NodeTraits>
2985 /   struct sgtree_algorithms;
2986 /
2987 /[classref boost::intrusive::sgtree_algorithms sgtree_algorithms]
2988 /is configured with a NodeTraits class, which encapsulates
2989 /the information about the node to be manipulated. NodeTraits must support the
2990 /following interface:
2991 /
2992 /[*Typedefs]:
2993 /
2994 /*  `node`: The type of the node that forms the circular sgtree
2995 /
2996 /*  `node_ptr`: The type of a pointer to a node (usually node*)
2997 /
2998 /*  `const_node_ptr`: The type of a pointer to a const node (usually const node*)
2999 /
3000 /[*Static functions]:
3001 /
3002 /*  `static node_ptr get_parent(const_node_ptr n);`:
3003 /   Returns a pointer to the parent node stored in "n".
3004 /
3005 /*  `static void set_parent(node_ptr n, node_ptr p);`:
3006 /   Sets the pointer to the parent node stored in "n" to "p".
3007 /
3008 /*  `static node_ptr get_left(const_node_ptr n);`:
3009 /   Returns a pointer to the left node stored in "n".
3010 /
3011 /*  `static void set_left(node_ptr n, node_ptr l);`:
3012 /   Sets the pointer to the left node stored in "n" to "l".
3013 /
3014 /*  `static node_ptr get_right(const_node_ptr n);`:
3015 /   Returns a pointer to the right node stored in "n".
3016 /
3017 /*  `static void set_right(node_ptr n, node_ptr r);`:
3018 /   Sets the pointer to the right node stored in "n" to "r".
3019 /
3020 /Once we have a node traits configuration we can use [*Boost.Intrusive] algorithms
3021 /with our nodes:
3022 /
3023 /[import ../example/doc_sgtree_algorithms.cpp]
3024 /[doc_sgtree_algorithms_code]
3025 /
3026 /For a complete list of functions see
3027 /[classref boost::intrusive::sgtree_algorithms sgtree_algorithms reference].
3028 /
3029 /[endsect]
3030 /]
3031
3032 [endsect]
3033
3034 [section:value_traits Containers with custom ValueTraits]
3035
3036 As explained in the [link intrusive.concepts Concepts] section, [*Boost.Intrusive]
3037 containers need a `ValueTraits` class to perform transformations between nodes and
3038 user values. `ValueTraits` can be explicitly configured (using the `value_traits<>` option)
3039 or implicitly configured (using hooks and their `base_hook<>`/`member_hook<>` options).
3040 `ValueTraits` contains
3041 all the information to glue the `value_type` of the containers and the node to be
3042 used in node algorithms, since these types can be different. Apart from this,
3043 `ValueTraits` also stores information about the link policy of the values to be inserted.
3044
3045 Instead of using [*Boost.Intrusive] predefined hooks
3046 a user might want to develop customized containers, for example, using nodes that are
3047 optimized for a specific
3048 application or that are compatible with a legacy ABI. A user might want
3049 to have only two additional pointers in his class and insert the class in a doubly
3050 linked list sometimes and in a singly linked list in other situations. You can't
3051 achieve this using [*Boost.Intrusive] predefined hooks. Now, instead of using
3052 `base_hook<...>` or `member_hook<...>` options the user will specify the
3053 `value_traits<...>` options. Let's see how we can do this:
3054
3055 [section:value_traits_interface ValueTraits interface]
3056
3057 `ValueTraits` has the following interface:
3058
3059 [c++]
3060
3061    #include <boost/intrusive/pointer_traits.hpp>
3062    #include <boost/intrusive/link_mode.hpp>
3063
3064    struct my_value_traits
3065    {
3066       typedef implementation_defined                                    node_traits;
3067       typedef implementation_defined                                    value_type;
3068       typedef node_traits::node_ptr                                     node_ptr;
3069       typedef node_traits::const_node_ptr                               const_node_ptr;
3070       typedef boost::intrusive::pointer_traits<node_ptr>::rebind_traits
3071          <value_type>::type::pointer                                    pointer;
3072       typedef boost::intrusive::pointer_traits<node_ptr>::rebind_traits
3073          <const value_type>::type::pointer                              const_pointer;
3074
3075       static const link_mode_type link_mode = some_linking_policy;
3076
3077       static node_ptr       to_node_ptr    (value_type &value);
3078       static const_node_ptr to_node_ptr    (const value_type &value);
3079       static pointer        to_value_ptr   (node_ptr n);
3080       static const_pointer  to_value_ptr   (const_node_ptr n);
3081    };
3082
3083 Let's explain each type and function:
3084
3085 *  [*['node_traits]]: The node configuration that is needed by node algorithms.
3086    These node traits and algorithms are
3087    described in the previous chapter: [link intrusive.node_algorithms Node Algorithms].
3088
3089    *  If my_value_traits is meant to be used with [classref boost::intrusive::slist slist],
3090       `node_traits` should follow
3091       the interface needed by [classref boost::intrusive::circular_slist_algorithms circular_slist_algorithms].
3092
3093    *  If my_value_traits is meant to be used with [classref boost::intrusive::list list],
3094       `node_traits` should follow
3095       the interface needed by [classref boost::intrusive::circular_list_algorithms circular_list_algorithms].
3096
3097    *  If my_value_traits is meant to be used with [classref boost::intrusive::set set]/[classref boost::intrusive::multiset multiset],
3098       `node_traits` should follow
3099       the interface needed by [classref boost::intrusive::rbtree_algorithms rbtree_algorithms].
3100
3101    *  If my_value_traits is meant to be used with [classref boost::intrusive::unordered_set unordered_set]/
3102       [classref boost::intrusive::unordered_multiset unordered_multiset], `node_traits`
3103       should follow the interface needed by [classref boost::intrusive::circular_slist_algorithms circular_slist_algorithms].
3104
3105 *  [*['node_ptr]]: A typedef for `node_traits::node_ptr`.
3106
3107 *  [*['const_node_ptr]]: A typedef for `node_traits::const_node_ptr`.
3108
3109 *  [*['value_type]]: The type that the user wants to insert in the container. This type can be
3110    the same as `node_traits::node` but it can be different (for example, `node_traits::node`
3111    can be a member type of `value_type`). If `value_type` and `node_traits::node` are the
3112    same type, the `to_node_ptr` and `to_value_ptr` functions are trivial.
3113
3114 *  [*['pointer]]: The type of a pointer to a `value_type`. It must be the same pointer type
3115    as `node_ptr`: If `node_ptr` is `node*`, `pointer` must be `value_type*`. If
3116    `node_ptr` is `smart_ptr<node_traits::node>`, `pointer` must be `smart_ptr<value_type>`.
3117    This can be generically achieved using `boost::intrusive::pointer_traits` (portable implementation of C++11
3118    `std::pointer_traits`).
3119
3120 *  [*['const_pointer]]: The type of a pointer to a `const value_type`. It must be the same pointer type
3121    as `node_ptr`: If `node_ptr` is `node*`, `const_pointer` must be `const value_type*`. If
3122    `node_ptr` is `smart_ptr<node_traits::node>`, `const_pointer` must be `smart_ptr<const value_type>`.
3123
3124 *  [*['link_mode]]: Indicates that `value_traits` needs some additional work or checks from the
3125    container. The types are enumerations defined in the `link_mode.hpp` header.
3126    These are the possible types:
3127
3128    *  [*`normal_link`]: If this linking policy is specified in a `ValueTraits` class
3129       as the link mode, containers
3130       configured with such `ValueTraits` won't set the hooks
3131       of the erased values to a default state. Containers also won't
3132       check that the hooks of the new values are default initialized.
3133
3134    *  [*`safe_link`]: If this linking policy is specified as the link mode
3135       in a `ValueTraits` class, containers
3136       configured with this `ValueTraits` will set the hooks
3137       of the erased values to a default state. Containers also will
3138       check that the hooks of the new values are default initialized.
3139
3140    *  [*`auto_unlink`]: Same as "safe_link" but containers with
3141       constant-time size features won't be
3142       compatible with `ValueTraits` configured with this policy.
3143       Containers also know that a value can be silently erased from
3144       the container without using any function provided by the containers.
3145
3146 *  [*['static node_ptr to_node_ptr (value_type &value)]] and
3147    [*['static const_node_ptr to_node_ptr (const value_type &value)]]:
3148    These functions take a reference to a value_type and return a pointer to the node
3149    to be used with node algorithms.
3150
3151 *  [*['static pointer to_value_ptr (node_ptr n)]] and
3152    [*['static const_pointer to_value_ptr (const_node_ptr n)]]:
3153    These functions take a pointer to a node and return a pointer to the value
3154    that contains the node.
3155
3156 [endsect]
3157
3158 [section:value_traits_example Custom ValueTraits example]
3159
3160 Let's define our own `value_traits` class to be able to use [*Boost.Intrusive]
3161 containers with an old C structure whose definition can't be changed.
3162 That legacy type has two pointers that can be used to build singly and doubly linked
3163 lists: in singly linked lists we only need a pointer, whereas in doubly
3164 linked lists, we need two pointers. Since we only have two pointers, we can't insert
3165 the object in both a singly and a doubly linked list at the same time.
3166 This is the definition of the old node:
3167
3168 [import ../example/doc_value_traits.cpp]
3169 [doc_value_traits_code_legacy]
3170
3171 Now we have to define a NodeTraits class that will implement the functions/typedefs
3172 that will make the legacy node compatible with [*Boost.Intrusive] algorithms. After that,
3173 we'll define a ValueTraits class that will configure [*Boost.Intrusive] containers:
3174
3175 [doc_value_traits_value_traits]
3176
3177 Defining a value traits class that simply defines `value_type` as
3178 `legacy_node_traits::node` is a common approach when defining customized
3179 intrusive containers, so [*Boost.Intrusive] offers a templatized
3180 [classref boost::intrusive::trivial_value_traits trivial_value_traits] class
3181 that does exactly what we want:
3182
3183 [doc_value_traits_trivial]
3184
3185 Now we can just define the containers that will store the legacy abi objects and write
3186 a little test:
3187
3188 [doc_value_traits_test]
3189
3190 As seen, several key elements of [*Boost.Intrusive] can be reused with custom user types,
3191 if the user does not want to use the provided [*Boost.Intrusive] facilities.
3192
3193 [endsect]
3194
3195 [section:reusing_node_algorithms Reusing node algorithms for different values]
3196
3197 In the previous example, `legacy_node_traits::node` type and
3198 `legacy_value_traits::value_type` are the same type, but this is not necessary. It's possible
3199 to have several `ValueTraits` defining the same `node_traits` type (and thus, the same `node_traits::node`).
3200 This reduces the number of node algorithm instantiations, but
3201 now `ValueTraits::to_node_ptr` and `ValueTraits::to_value_ptr` functions need to offer
3202 conversions between both types. Let's see a small example:
3203
3204 First, we'll define the node to be used in the algorithms. For a linked list,
3205 we just need a node that stores two pointers:
3206
3207 [import ../example/doc_advanced_value_traits.cpp]
3208 [doc_advanced_value_traits_code]
3209
3210 Now we'll define two different types that will be inserted in intrusive lists and
3211 a templatized `ValueTraits` that will work for both types:
3212
3213 [doc_advanced_value_traits_value_traits]
3214
3215 Now define two containers. Both containers will instantiate the same list algorithms
3216 (`circular_list_algorithms<simple_node_traits>`),
3217 due to the fact that the value traits used to define the containers provide the same `node_traits` type:
3218
3219 [doc_advanced_value_traits_containers]
3220
3221 All [*Boost.Intrusive] containers using predefined hooks use this technique to minimize code size:
3222 all possible [classref boost::intrusive::list list] containers
3223 created with predefined hooks that define the same `VoidPointer` type
3224 share the same list algorithms.
3225
3226 [endsect]
3227
3228 [section:simplifying_value_traits Simplifying value traits definition]
3229
3230 The previous example can be further simplified using the
3231 [classref boost::intrusive::derivation_value_traits derivation_value_traits]
3232 class to define a value traits class with a value that stores the
3233 `simple_node` as a base class:
3234
3235 [import ../example/doc_derivation_value_traits.cpp]
3236 [doc_derivation_value_traits_value_traits]
3237
3238 We can even choose to store `simple_node` as a member of `value_1` and `value_2`
3239 classes and use [classref boost::intrusive::member_value_traits member_value_traits]
3240 to define the needed value traits classes:
3241
3242 [import ../example/doc_member_value_traits.cpp]
3243 [doc_member_value_traits_value_traits]
3244
3245 [endsect]
3246
3247 [section:stateful_value_traits Stateful value traits]
3248
3249 Until now all shown custom value traits are stateless, that is, [*the transformation between nodes
3250 and values is implemented in terms of static functions]. It's possible to use [*stateful] value traits
3251 so that we can separate nodes and values and [*avoid modifying types to insert nodes].
3252 [*Boost.Intrusive] differentiates between stateful and stateless value traits by checking if all
3253 Node <-> Value transformation functions are static or not (except for Visual 7.1, since overloaded
3254 static function detection is not possible, in this case the implementation checks if the class is empty):
3255
3256 *  If all Node <-> Value transformation functions are static , a [*stateless]
3257    value traits is assumed.  transformations must be static functions.
3258 *  Otherwise a [*stateful] value traits is assumed.
3259
3260 Using stateful value traits it's possible to create containers of non-copyable/movable objects [*without modifying]
3261 the definition of the class to be inserted. This interesting property is achieved without using global variables
3262 (stateless value traits could use global variables to achieve the same goal), so:
3263
3264 *  [*Thread-safety guarantees]: Better thread-safety guarantees can be achieved with stateful
3265    value traits, since accessing global resources might require synchronization primitives that
3266    can be avoided when using internal state.
3267 *  [*Flexibility]: A stateful value traits type can be configured at run-time.
3268 *  [*Run-time polymorphism]: A value traits might implement node <-> value
3269    transformations as virtual functions. A single container type could be
3270    configured at run-time to use different node <-> value relationships.
3271
3272 Stateful value traits have many advantages but also some downsides:
3273
3274 *  [*Performance]: Value traits operations should be very efficient since they are basic operations used by containers.
3275    [*A heavy node <-> value transformation will hurt intrusive containers' performance].
3276 *  [*Exception guarantees]: The stateful ValueTraits must maintain no-throw guarantees, otherwise, the
3277    container invariants won't be preserved.
3278 *  [*Static functions]: Some static functions offered by intrusive containers are not
3279    available because node <-> value transformations are not static.
3280 *  [*Bigger iterators]: The size of some iterators is increased because the iterator
3281    needs to store a pointer to the stateful value traits to implement node to value
3282    transformations (e.g. `operator*()` and `operator->()`).
3283
3284 An easy and useful example of stateful value traits is when an array of values can be indirectly introduced
3285 in a list guaranteeing no additional allocation apart from the initial resource reservation:
3286
3287 [import ../example/doc_stateful_value_traits.cpp]
3288 [doc_stateful_value_traits]
3289
3290 [endsect]
3291
3292 [endsect]
3293
3294 [section:thread_safety Thread safety guarantees]
3295
3296 Intrusive containers have thread safety guarantees similar to STL containers.
3297
3298 *  Several threads having read or write access to different instances is safe as long as inserted
3299    objects are different.
3300 *  Concurrent read-only access to the same container is safe.
3301
3302 Some Intrusive hooks (auto-unlink hooks, for example) modify containers without
3303 having a reference to them: this is considered a write access to the container.
3304
3305 Other functions, like checking if an object is already inserted in a container using the `is_linked()`
3306 member of safe hooks, constitute read access on the container without having a reference to it, so no other
3307 thread should have write access (direct or indirect) to that container.
3308
3309 Since the same object can be inserted in several containers at the same time using different hooks,
3310 the thread safety of [*Boost.Intrusive] is related to the containers and also to the object whose lifetime
3311 is manually managed by the user.
3312
3313 As we can see, the analysis of the thread-safety of a program using [*Boost.Intrusive] is harder
3314 than with non-intrusive containers.
3315
3316 To analyze the thread safety, consider the following points:
3317
3318 *  The auto-unlink hook's destructor and `unlink()` functions modify the container indirectly.
3319 *  The safe mode and auto-unlink hooks' `is_linked()` functions are a read access to the container.
3320 *  Inserting an object in containers that will be modified by different threads has no thread safety
3321    guarantee, although in most platforms it will be thread-safe without locking.
3322
3323 [endsect]
3324
3325 [section:boost_intrusive_iterators Boost.Intrusive Iterator features]
3326
3327 [section:null_forward_iterators Null forward iterators]
3328
3329 [*Boost.Intrusive] implements
3330 [@http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3644.pdf C++14 Null Forward Iterators],
3331 a feature that was introduced with C++14. This means that equality and inequality comparison are defined
3332 over all iterators for the same underlying sequence and the value initialized-iterators.
3333
3334 Value initialized iterators behave as if they refer past the end of the same empty sequence:
3335
3336 [c++]
3337
3338    list<MyType> l = { ... };
3339    auto ni = list<MyType>::iterator();
3340    auto nd = list<MyType2>::iterator();
3341    ni == ni; // True.
3342    nd != nd; // False.
3343    ni == nd; // Won't compile.
3344
3345 [endsect]
3346
3347 [section:scary_iterators Scary Iterators]
3348
3349 The paper N2913, titled [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2913.pdf,
3350 SCARY Iterator Assignment and Initialization], proposed a requirement that a standard container's
3351 iterator types have no dependency on any type argument apart from the container's `value_type`,
3352 `difference_type`, `pointer type`, and `const_pointer` type. In particular, according to the proposal,
3353 the types of a standard container's iterators should not depend on the container's `key_compare`,
3354 `hasher`, `key_equal`, or `allocator` types.
3355
3356 That paper demonstrated that SCARY operations were crucial to the performant implementation of common
3357 design patterns using STL components. It showed that implementations that support SCARY operations reduce
3358 object code bloat by eliminating redundant specializations of iterator and algorithm templates.
3359
3360 [*Boost.Intrusive] containers are a bit different from standard containers. In particular, they have no
3361 allocator parameter and they can be configured with additional options not present in STL-like containers.
3362 Thus [*Boost.Intrusive] offers its own `SCARY iterator` implementation, where iterator types don't
3363 change when the container is configured with an option that does not alter the value <-> node transformation.
3364 More concretely, the following options and conditions guarantee that iterator types are unchanged:
3365
3366 * [*All containers]: `size_type<>`, `constant_time_size<>`,
3367 * [*`slist`]: `cache_last<>`, `linear<>`,
3368 * [*`unordered_[multi]set`]: `hash<>`, `equal<>`, `power_2_buckets<>`, `cache_begin<>`.
3369 * [*All tree-like containers] (`[multi]set`, `avl_[multi]set`, `sg_[multi]set`, `bs_[multi]set`,
3370    `splay_[multi]set`, `treap_[multi]set`): `compare<>`.
3371 * [*`treap_[multi]set`]: `priority<>`
3372 * [*`bs_[multi]set`, `sg_[multi]set`, `treap_[multi]set`, `splay_[multi]set`]:
3373    They share the same iterator type when configured with the same options.
3374
3375 [endsect]
3376
3377 [endsect]
3378
3379 [section:equal_range_stability Stability and insertion with hint in ordered associative containers with equivalent keys]
3380
3381 [*Boost.Intrusive] ordered associative containers with equivalent keys offer stability guarantees, following
3382 [@http://open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#233 C++ standard library's defect #233 resolution],
3383 explained in document [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html Comments on LWG issue 233: Insertion hints in associative containers].
3384 This means that:
3385
3386 *  A ['Insert without hint] member function always insert at the upper bound of an equal range.
3387 *  A ['Insert with hint] member function inserts the new value [*before the hint] if hint's and new node's keys are equivalent.
3388 *  Implements Andrew Koenig ['as close as possible to hint] proposal. A new element is always be inserted as close to the hint as possible.
3389    So, for example, if there is a subsequence of equivalent values, `a.begin()` as the hint means that the new element should be inserted
3390    before the subsequence even if `a.begin()` is far away. This allows code to always append (or prepend) an equal range with something
3391    as simple as: `m.insert(m.end(), new_node);` or `m.insert(m.begin(), new_node);`
3392
3393 [endsect]
3394
3395 [section:obtaining_same_type_reducing_space Obtaining the same types and reducing symbol length]
3396
3397 The flexible option specification mechanism used by [*Boost.Intrusive] for hooks and containers
3398 has a couple of downsides:
3399
3400 *  If a user specifies the same options in different order or specifies some options and leaves the
3401    rest as defaults, the type of the created container/hook will be different. Sometimes
3402    this is annoying, because two programmers specifying the same options might end up with incompatible
3403    types. For example, the following two lists, although using the same options, do not have
3404    the same type:
3405
3406 [c++]
3407
3408    #include <boost/intrusive/list.hpp>
3409
3410    using namespace boost::intrusive;
3411
3412    //Explicitly specify constant-time size and size type
3413    typedef list<T, constant_time_size<true>, size_type<std::size_t> List1;
3414
3415    //Implicitly specify constant-time size and size type
3416    typedef list<T> List2;
3417
3418 *  Option specifiers lead to long template symbols for classes and functions. Option specifiers themselves
3419    are verbose and without variadic templates, several default template parameters are assigned for
3420    non-specified options. Object and debugging information files can grow and compilation times
3421    may suffer if long names are produced.
3422
3423 To solve these issues [*Boost.Intrusive] offers some helper metafunctions that reduce symbol lengths
3424 and create the same type if the same options (either explicitly or implicitly) are used. These also
3425 improve compilation times. All containers and hooks have their respective `make_xxx` versions.
3426 The previously shown example can be rewritten like this to obtain the same list type:
3427
3428 [c++]
3429
3430   #include <boost/intrusive/list.hpp>
3431
3432    using namespace boost::intrusive;
3433
3434    #include <boost/intrusive/list.hpp>
3435
3436    using namespace boost::intrusive;
3437
3438    //Explicitly specify constant-time size and size type
3439    typedef make_list<T, constant_time_size<true>, size_type<std::size_t>::type List1;
3440
3441    //Implicitly specify constant-time size and size type
3442    typedef make_list<T>::type List2;
3443
3444 Produced symbol lengths and compilation times will usually be shorter and object/debug files smaller.
3445 If you are concerned with file sizes and compilation times, this option is your best choice.
3446
3447 [endsect]
3448
3449 [section:design_notes Design Notes]
3450
3451 When designing [*Boost.Intrusive] the following guidelines have been taken into account:
3452
3453 [section:performance_sensitive Boost.Intrusive in performance sensitive environments]
3454
3455 [*Boost.Intrusive] should be a valuable tool in performance sensitive environments,
3456 and following this guideline, [*Boost.Intrusive] has been designed to offer well
3457 known complexity guarantees. Apart from that, some options, like optional
3458 constant-time, have been designed to offer faster complexity guarantees in some
3459 functions, like `slist::splice`.
3460
3461 The advanced lookup and insertion functions for associative containers, taking
3462 an arbitrary key type and predicates, were designed to avoid unnecessary object
3463 constructions.
3464
3465 [endsect]
3466
3467 [section:space_constrained Boost.Intrusive in space constrained environments]
3468
3469 [*Boost.Intrusive] should be useful in space constrained environments,
3470 and following this guideline [*Boost.Intrusive] separates node algorithms
3471 and intrusive containers to avoid instantiating node algorithms for each
3472 user type. For example, a single class of red-black algorithms will be instantiated
3473 to implement all set and multiset containers using raw pointers. This way,
3474 [*Boost.Intrusive] seeks to avoid any code size overhead associated with templates.
3475
3476 Apart from that, [*Boost.Intrusive] implements some size improvements: for example,
3477 red-black trees embed the color bit in the parent pointer lower bit, if nodes
3478 are two-byte aligned. The option to forgo constant-time size operations can
3479 reduce container size, and this extra size optimization is noticeable
3480 when the container is empty or contains few values.
3481
3482 [endsect]
3483
3484 [section:basic_building_block Boost.Intrusive as a basic building block]
3485
3486 [*Boost.Intrusive] can be a basic building block to build more complex containers
3487 and this potential has motivated many design decisions. For example, the ability
3488 to have more than one hook per user type opens the opportunity to implement multi-index
3489 containers on top of [*Boost.Intrusive].
3490
3491 [*Boost.Intrusive] containers implement advanced functions taking function objects
3492 as arguments (`clone_from`, `erase_and_dispose`, `insert_check`, etc.). These
3493 functions come in handy when implementing non-intrusive containers
3494 (for example, STL-like containers) on top of intrusive containers.
3495
3496 [endsect]
3497
3498 [section:extending_intrusive Extending Boost.Intrusive]
3499
3500 [*Boost.Intrusive] offers a wide range of containers but also allows the
3501 construction of custom containers reusing [*Boost.Intrusive] elements.
3502 The programmer might want to use node algorithms directly or
3503 build special hooks that take advantage of an application environment.
3504
3505 For example, the programmer can customize parts of [*Boost.Intrusive]
3506 to manage old data structures whose definition can't be changed.
3507
3508 [endsect]
3509
3510 [endsect]
3511
3512 [section:performance Performance]
3513
3514 [*Boost.Intrusive] containers offer speed improvements compared to non-intrusive containers
3515 primarily because:
3516
3517 *  They minimize memory allocation/deallocation calls.
3518 *  They obtain better memory locality.
3519
3520 This section will show performance tests comparing some operations on
3521 `boost::intrusive::list` and `std::list`:
3522
3523 *  Insertions using `push_back` and container destruction will show the
3524    overhead associated with memory allocation/deallocation.
3525 *  The `reverse` member function will show the advantages of the compact
3526    memory representation that can be achieved with intrusive containers.
3527 *  The `sort` and `write access` tests will show the advantage of intrusive containers
3528    minimizing memory accesses compared to containers of pointers.
3529
3530 Given an object of type `T`, [classref boost::intrusive::list boost::intrusive::list<T>]
3531 can replace `std::list<T>` to avoid memory allocation overhead,
3532 or it can replace `std::list<T*>` when the user wants containers with
3533 polymorphic values or wants to share values between several containers.
3534 Because of this versatility, the performance tests will be executed for 6 different
3535 list types:
3536
3537 *  3 intrusive lists holding a class named `itest_class`,
3538    each one with a different linking policy (`normal_link`, `safe_link`, `auto_unlink`).
3539    The `itest_class` objects will be tightly packed in a `std::vector<itest_class>` object.
3540
3541 *  `std::list<test_class>`, where `test_class` is exactly the same as `itest_class`,
3542    but without the intrusive hook.
3543
3544 *  `std::list<test_class*>`. The list will contain pointers to `test_class` objects
3545    tightly packed in a `std::vector<test_class>` object. We'll call this configuration ['compact pointer list]
3546
3547 *  `std::list<test_class*>`. The list will contain pointers to `test_class` objects owned by a
3548    `std::list<test_class>` object. We'll call this configuration ['disperse pointer list].
3549
3550 Both `test_class` and `itest_class` are templatized classes that can be configured with
3551 a boolean to increase the size of the object. This way, the tests can be executed with
3552 small and big objects. Here is the first part of the testing code, which shows
3553 the definitions of `test_class` and `itest_class` classes, and some other
3554 utilities:
3555
3556 [import ../perf/perf_list.cpp]
3557 [perf_list_value_type]
3558
3559 As we can see, `test_class` is a very simple class holding an `int`. `itest_class`
3560 is just a class that has a base hook ([classref boost::intrusive::list_base_hook list_base_hook])
3561 and also derives from `test_class`.
3562
3563 `func_ptr_adaptor` is just a functor adaptor to convert function objects taking
3564 `test_list` objects to function objects taking pointers to them.
3565
3566 You can find the full test code in the
3567 [@../../libs/intrusive/perf/perf_list.cpp perf_list.cpp] source file.
3568
3569 [section:performance_results_push_back Back insertion and destruction]
3570
3571 The first test will measure the benefits we can obtain with intrusive containers
3572 avoiding memory allocations and deallocations. All the objects to be
3573 inserted in intrusive containers are allocated in a single allocation call,
3574 whereas `std::list` will need to allocate memory for each object and deallocate it
3575 for every erasure (or container destruction).
3576
3577 Let's compare the code to be executed for each container type for different insertion tests:
3578
3579 [perf_list_push_back_intrusive]
3580
3581 For intrusive containers, all the values are created in a vector and after that
3582 inserted in the intrusive list.
3583
3584 [perf_list_push_back_stdlist]
3585
3586 For a standard list, elements are pushed back using push_back().
3587
3588 [perf_list_push_back_stdptrlist]
3589
3590 For a standard compact pointer list, elements are created in a vector and pushed back
3591 in the pointer list using push_back().
3592
3593 [perf_list_push_back_disperse_stdptrlist]
3594
3595 For a ['disperse pointer list], elements are created in a list and pushed back
3596 in the pointer list using push_back().
3597
3598 These are the times in microseconds for each case, and the normalized time:
3599
3600 [table Back insertion + destruction times for Visual C++ 7.1 / Windows XP
3601     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3602     [[`normal_link` intrusive list]     [5000 / 22500]                        [1 / 1]]
3603     [[`safe_link` intrusive list]       [7812 / 32187]                        [1.56 / 1.43]]
3604     [[`auto_unlink` intrusive list]     [10156 / 41562]                       [2.03 / 1.84]]
3605     [[Standard list]                    [26875 / 97500]                       [5.37 / 4.33]]
3606     [[Standard compact pointer list]    [76406 / 86718]                      [15.28 / 3.85]]
3607     [[Standard disperse pointer list]  [146562 / 175625]                     [29.31 / 7.80]]
3608 ]
3609
3610 [table Back insertion + destruction times for GCC 4.1.1 / MinGW over Windows XP
3611     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3612     [[`normal_link` intrusive list]     [4375 / 22187]                  [1 / 1]]
3613     [[`safe_link` intrusive list]       [7812 / 32812]                  [1.78 / 1.47]]
3614     [[`auto_unlink` intrusive list]     [10468 / 42031]                 [2.39 / 1.89]]
3615     [[Standard list]                    [81250 / 98125]                [18.57 / 4.42]]
3616     [[Standard compact pointer list]    [83750 / 94218]                [19.14 / 4.24]]
3617     [[Standard disperse pointer list]  [155625 / 175625]                [35.57 / 7.91]]
3618 ]
3619
3620 [table Back insertion + destruction times for GCC 4.1.2 / Linux Kernel 2.6.18 (OpenSuse 10.2)
3621     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3622     [[`normal_link` intrusive list]     [4792 / 20495]                  [1 / 1]]
3623     [[`safe_link` intrusive list]       [7709 / 30803]                  [1.60 / 1.5]]
3624     [[`auto_unlink` intrusive list]     [10180 / 41183]                 [2.12 / 2.0]]
3625     [[Standard list]                    [17031 / 32586]                 [3.55 / 1.58]]
3626     [[Standard compact pointer list]    [27221 / 34823]                 [5.68 / 1.69]]
3627     [[Standard disperse pointer list]  [102272 / 60056]                [21.34 / 2.93]]
3628 ]
3629
3630 The results are logical: intrusive lists just need one allocation. The destruction
3631 time of the `normal_link` intrusive container is trivial (complexity: `O(1)`),
3632 whereas `safe_link` and `auto_unlink` intrusive containers need to put the hooks of
3633 erased values in the default state (complexity: `O(NumElements)`). That's why
3634 `normal_link` intrusive list shines in this test.
3635
3636 Non-intrusive containers need to make many more allocations and that's why they
3637 lag behind. The `disperse pointer list` needs to make `NumElements*2` allocations,
3638 so the result is not surprising.
3639
3640 The Linux test shows that standard containers perform very well against intrusive containers
3641 with big objects. Nearly the same GCC version in MinGW performs worse, so maybe
3642 a good memory allocator is the reason for these excellent results.
3643
3644 [endsect]
3645
3646 [section:performance_results_reversing Reversing]
3647
3648 The next test measures the time needed to complete calls to the member function `reverse()`.
3649 Values (`test_class` and `itest_class`) and lists are created as explained in the
3650 previous section.
3651
3652 Note that for pointer lists, `reverse` [*does not need to access `test_class` values
3653 stored in another list or vector],
3654 since this function just needs to adjust internal pointers, so in theory all tested
3655 lists need to perform the same operations.
3656
3657 These are the results:
3658
3659 [table Reverse times for Visual C++ 7.1 / Windows XP
3660     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3661     [[`normal_link` intrusive list]     [2656 / 10625]                 [1 / 1.83]]
3662     [[`safe_link` intrusive list]       [2812 / 10937]                 [1.05 / 1.89]]
3663     [[`auto_unlink` intrusive list]     [2710 / 10781]                 [1.02 / 1.86]]
3664     [[Standard list]                    [5781 / 14531]                 [2.17 / 2.51]]
3665     [[Standard compact pointer list]    [5781 / 5781]                  [2.17 / 1]]
3666     [[Standard disperse pointer list]  [10781 / 15781]                 [4.05 / 2.72]]
3667 ]
3668
3669 [table Reverse times for GCC 4.1.1 / MinGW over Windows XP
3670     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3671     [[`normal_link` intrusive list]     [2656 / 10781]                 [1 / 2.22]]
3672     [[`safe_link` intrusive list]       [2656 / 10781]                 [1 / 2.22]]
3673     [[`auto_unlink` intrusive list]     [2812 / 10781]                 [1.02 / 2.22]]
3674     [[Standard list]                    [4843 / 12500]                 [1.82 / 2.58]]
3675     [[Standard compact pointer list]    [4843 / 4843]                  [1.82 / 1]]
3676     [[Standard disperse pointer list]   [9218 / 12968]                 [3.47 / 2.67]]
3677 ]
3678
3679 [table Reverse times for GCC 4.1.2 / Linux Kernel 2.6.18 (OpenSuse 10.2)
3680     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3681     [[`normal_link` intrusive list]     [2742 / 10847]                 [1 / 3.41]]
3682     [[`safe_link` intrusive list]       [2742 / 10847]                 [1 / 3.41]]
3683     [[`auto_unlink` intrusive list]     [2742 / 11027]                 [1 / 3.47]]
3684     [[Standard list]                    [3184 / 10942]                 [1.16 / 3.44]]
3685     [[Standard compact pointer list]    [3207 / 3176]                  [1.16 / 1]]
3686     [[Standard disperse pointer list]   [5814 / 13381]                 [2.12 / 4.21]]
3687 ]
3688
3689 For small objects the results show that the compact storage of values in intrusive
3690 containers improve locality and reversing is faster than with standard containers,
3691 whose values might be dispersed in memory because each value is independently
3692 allocated. Note that the dispersed pointer list (a list of pointers to values
3693 allocated in another list) suffers more because nodes of the pointer list
3694 might be more dispersed, since allocations from both lists are interleaved
3695 in the code:
3696
3697 [c++]
3698
3699    //Object list (holding `test_class`)
3700    stdlist objects;
3701
3702    //Pointer list (holding `test_class` pointers)
3703    stdptrlist l;
3704
3705    for(int i = 0; i < NumElements; ++i){
3706       //Allocation from the object list
3707       objects.push_back(stdlist::value_type(i));
3708       //Allocation from the pointer list
3709       l.push_back(&objects.back());
3710    }
3711
3712 For big objects the compact pointer list wins because the reversal test doesn't need access
3713 to values stored in another container. Since all the allocations for nodes of
3714 this pointer list are likely to be close (since there is no other allocation in the
3715 process until the pointer list is created) locality is better than with intrusive
3716 containers. The dispersed pointer list, as with small values, has poor locality.
3717
3718 [endsect]
3719
3720 [section:performance_results_sorting Sorting]
3721
3722 The next test measures the time needed to complete calls to the member function
3723 `sort(Pred pred)`. Values (`test_class` and `itest_class`) and lists are created as explained in the
3724 first section. The values will be sorted in ascending and descending order each
3725 iteration. For example, if ['l] is a list:
3726
3727 [c++]
3728
3729    for(int i = 0; i < NumIter; ++i){
3730       if(!(i % 2))
3731          l.sort(std::greater<stdlist::value_type>());
3732       else
3733          l.sort(std::less<stdlist::value_type>());
3734    }
3735
3736 For a pointer list, the function object will be adapted using `func_ptr_adaptor`:
3737
3738 [c++]
3739
3740    for(int i = 0; i < NumIter; ++i){
3741       if(!(i % 2))
3742          l.sort(func_ptr_adaptor<std::greater<stdlist::value_type> >());
3743       else
3744          l.sort(func_ptr_adaptor<std::less<stdlist::value_type> >());
3745    }
3746
3747 Note that for pointer lists, `sort` will take a function object that [*will access
3748 `test_class` values stored in another list or vector], so pointer lists will suffer
3749 an extra indirection: they will need to access the `test_class` values stored in
3750 another container to compare two elements.
3751
3752 These are the results:
3753
3754 [table Sort times for Visual C++ 7.1 / Windows XP
3755     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3756     [[`normal_link` intrusive list]     [16093 / 38906]                [1 / 1]]
3757     [[`safe_link` intrusive list]       [16093 / 39062]                [1 / 1]]
3758     [[`auto_unlink` intrusive list]     [16093 / 38906]                [1 / 1]]
3759     [[Standard list]                    [32343 / 56406]                [2.0 / 1.44]]
3760     [[Standard compact pointer list]    [33593 / 46093]                [2.08 / 1.18]]
3761     [[Standard disperse pointer list]   [46875 / 68593]                [2.91 / 1.76]]
3762 ]
3763
3764 [table Sort times for GCC 4.1.1 / MinGW over Windows XP
3765     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3766     [[`normal_link` intrusive list]     [15000 / 39218]                [1 / 1]]
3767     [[`safe_link` intrusive list]       [15156 / 39531]                [1.01 / 1.01]]
3768     [[`auto_unlink` intrusive list]     [15156 / 39531]                [1.01 / 1.01]]
3769     [[Standard list]                    [34218 / 56875]                [2.28 / 1.45]]
3770     [[Standard compact pointer list]    [35468 / 49218]                [2.36 / 1.25]]
3771     [[Standard disperse pointer list]   [47656 / 70156]                [3.17 / 1.78]]
3772 ]
3773
3774 [table Sort times for GCC 4.1.2 / Linux Kernel 2.6.18 (OpenSuse 10.2)
3775     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3776     [[`normal_link` intrusive list]     [18003 / 40795]                [1 / 1]]
3777     [[`safe_link` intrusive list]       [18003 / 41017]                [1 / 1]]
3778     [[`auto_unlink` intrusive list]     [18230 / 40941]                [1.01 / 1]]
3779     [[Standard list]                    [26273 / 49643]                [1.45 / 1.21]]
3780     [[Standard compact pointer list]    [28540 / 43172]                [1.58 / 1.05]]
3781     [[Standard disperse pointer list]   [35077 / 57638]                [1.94 / 1.41]]
3782 ]
3783
3784 The results show that intrusive containers are faster than standard
3785 containers. We can see that the pointer
3786 list holding pointers to values stored in a vector is quite fast, so the extra
3787 indirection that is needed to access the value is minimized because all the values
3788 are tightly stored, improving caching. The disperse list, on the other hand, is
3789 slower because the indirection to access values stored in the object list is
3790 more expensive than accessing values stored in a vector.
3791
3792 [endsect]
3793
3794 [section:performance_results_write_access Write access]
3795
3796 The next test measures the time needed to iterate through all the elements of a list, and
3797 increment the value of the internal `i_` member:
3798
3799 [c++]
3800
3801    stdlist::iterator it(l.begin()), end(l.end());
3802    for(; it != end; ++it)
3803       ++(it->i_);
3804
3805 Values (`test_class` and `itest_class`) and lists are created as explained in
3806 the first section. Note that for pointer lists, the iteration will suffer
3807 an extra indirection: they will need to access the `test_class` values stored in
3808 another container:
3809
3810 [c++]
3811
3812    stdptrlist::iterator it(l.begin()), end(l.end());
3813    for(; it != end; ++it)
3814       ++((*it)->i_);
3815
3816 These are the results:
3817
3818 [table Write access times for Visual C++ 7.1 / Windows XP
3819     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3820     [[`normal_link` intrusive list]     [2031 / 8125]                 [1 / 1]]
3821     [[`safe_link` intrusive list]       [2031 / 8281]                 [1 / 1.01]]
3822     [[`auto_unlink` intrusive list]     [2031 / 8281]                 [1 / 1.01]]
3823     [[Standard list]                    [4218 / 10000]                [2.07 / 1.23]]
3824     [[Standard compact pointer list]    [4062 / 8437]                 [2.0 / 1.03]]
3825     [[Standard disperse pointer list]   [8593 / 13125]                [4.23 / 1.61]]
3826 ]
3827
3828 [table Write access times for GCC 4.1.1 / MinGW over Windows XP
3829     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3830     [[`normal_link` intrusive list]     [2343 / 8281]                 [1 / 1]]
3831     [[`safe_link` intrusive list]       [2500 / 8281]                 [1.06 / 1]]
3832     [[`auto_unlink` intrusive list]     [2500 / 8281]                 [1.06 / 1]]
3833     [[Standard list]                    [4218 / 10781]                [1.8 / 1.3]]
3834     [[Standard compact pointer list]    [3906 / 8281]                 [1.66 / 1]]
3835     [[Standard disperse pointer list]   [8281 / 13750]                [3.53 / 1.66]]
3836 ]
3837
3838 [table Write access times for GCC 4.1.2 / Linux Kernel 2.6.18 (OpenSuse 10.2)
3839     [[Container]                       [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
3840     [[`normal_link` intrusive list]     [2286 / 8468]                 [1 / 1.1]]
3841     [[`safe_link` intrusive list]       [2381 / 8412]                 [1.04 / 1.09]]
3842     [[`auto_unlink` intrusive list]     [2301 / 8437]                 [1.01 / 1.1]]
3843     [[Standard list]                    [3044 / 9061]                 [1.33 / 1.18]]
3844     [[Standard compact pointer list]    [2755 / 7660]                 [1.20 / 1]]
3845     [[Standard disperse pointer list]   [6118 / 12453]                [2.67 / 1.62]]
3846 ]
3847
3848 As with the read access test, the results show that intrusive containers outperform
3849 all other containers if the values are tightly packed in a vector.
3850 The disperse list is again the slowest.
3851
3852 [endsect]
3853
3854 [section:performance_results_conclusions Conclusions]
3855
3856 Intrusive containers can offer performance benefits that cannot be achieved with
3857 equivalent non-intrusive containers. Memory locality improvements are noticeable
3858 when the objects to be inserted are small. Minimizing memory allocation/deallocation calls is also
3859 an important factor and intrusive containers make this simple if all objects
3860 to be inserted in intrusive containers are allocated using `std::vector` or `std::deque`.
3861
3862 [endsect]
3863
3864 [endsect]
3865
3866 [section:release_notes Release Notes]
3867
3868 [section:release_notes_boost_1_65_00 Boost 1.65 Release]
3869
3870 *  Fixed bugs:
3871    *  [@https://svn.boost.org/trac/boost/ticket/12894 Boost Trac #12894: ['Allow non std::size_t size_type]]
3872
3873 [endsect]
3874
3875 [section:release_notes_boost_1_64_00 Boost 1.64 Release]
3876
3877 *  Fixed bugs:
3878    *  [@https://svn.boost.org/trac/boost/ticket/12745 Boost Trac #12745: ['key_nodeptr_comp broken if the key type is void*]]
3879    *  [@https://svn.boost.org/trac/boost/ticket/12761 Boost Trac #12761: ['intrusive::set::swap doesn't swap the comparison function*]]
3880
3881 [endsect]
3882
3883 [section:release_notes_boost_1_63_00 Boost 1.63 Release]
3884
3885 *  Fixed bugs:
3886    *  [@https://svn.boost.org/trac/boost/ticket/12556 Boost Trac #12556: ['member_value_traits.hpp has a missing #include]]
3887
3888 [endsect]
3889
3890 [section:release_notes_boost_1_62_00 Boost 1.62 Release]
3891
3892 *  Fixed bugs:
3893    *  [@https://svn.boost.org/trac/boost/ticket/11476 Boost Trac #11476: ['has_member_function_callable_with.hpp is massively broken with BOOST_NO_CXX11_DECLTYPE]]
3894    *  [@https://svn.boost.org/trac/boost/ticket/11994 Boost Trac #11994: ['Support intrusive container key extractors that return the key by value]]
3895    *  [@https://svn.boost.org/trac/boost/ticket/12184 Boost Trac #12184: ['clang -Wdocumentation warning]]
3896    *  [@https://svn.boost.org/trac/boost/ticket/12190 Boost Trac #12190: ['Intrusive List + Flat Map combination crashes]]
3897    *  [@https://svn.boost.org/trac/boost/ticket/12229 Boost Trac #12229: ['intrusive::unordered_set<T>::rehash() broken]]
3898    *  [@https://svn.boost.org/trac/boost/ticket/12245 Boost Trac #12245: ['bstree uses a shared static size_traits for constant_time_size<false>]]
3899    *  [@https://svn.boost.org/trac/boost/ticket/12432 Boost Trac #12432: ['Forced KeyOfValue creation when using custom compare on insert_check]]
3900
3901 *  Implemented `merge` functions in ordered associative containers.
3902 *  Officially documented `root()` function for tree-based containers.
3903
3904 [endsect]
3905
3906 [section:release_notes_boost_1_61_00 Boost 1.61 Release]
3907
3908 *  Fixed bugs:
3909    *  [@https://svn.boost.org/trac/boost/ticket/11832 Boost Trac #11832: ['clang-cl + boost intrusive = miscompile]]
3910    *  [@https://svn.boost.org/trac/boost/ticket/11865 Boost Trac #11865: ['Intrusive list explicit ctor error with Clang 3.6 (C++11/14)]]
3911    *  [@https://svn.boost.org/trac/boost/ticket/11992 Boost Trac #11992: ['Add an overload of insert_check taking a key_type]]
3912    *  [@https://github.com/boostorg/intrusive/pull/19 GitHub Pull #19: ['ebo_functor_holder: compile fix for copy constructor]]
3913
3914 [endsect]
3915
3916 [section:release_notes_boost_1_60_00 Boost 1.60 Release]
3917
3918 *  [link intrusive.advanced_lookups_insertions Advanced lookup and insertions] in ordered associative containers
3919    now support comparison functions that are not required to offer the same strict weak ordering as `key_compare`,
3920    the container must be partitioned in regards to the passed comparison object.
3921 *  Fixed bugs:
3922    *  [@https://svn.boost.org/trac/boost/ticket/11701 Boost Trac #11701: ['Regression in boost::intrusive::set::equal_range]]
3923    *  [@https://svn.boost.org/trac/boost/ticket/11765 Boost Trac #11765: ['sgtree.hpp:830: bad if test ?]]
3924
3925 [endsect]
3926
3927 [section:release_notes_boost_1_59_00 Boost 1.59 Release]
3928
3929 *  Implemented [link intrusive.map_multimap map and multimap-like interfaces].
3930 *  Refactored hashtable containers to reduce template instantiations.
3931 *  Fixed bugs:
3932    *  [@https://svn.boost.org/trac/boost/ticket/11222 Boost Trac #11222: ['intrusive/pointer_traits.hpp fails to compile with C++98]]
3933
3934 [endsect]
3935
3936 [section:release_notes_boost_1_58_00 Boost 1.58 Release]
3937
3938 *  Reduced compile-time dependencies, headers, and the use of Boost.Preprocessor, specially for hooks and iterators.
3939 *  Fixed bugs:
3940    *  [@https://svn.boost.org/trac/boost/ticket/6720  Boost Trac #6720: ['intrusive::unordered_set::clear_and_dispose does not compile on VC11 Beta when passed a stateless lambda]]
3941    *  [@https://svn.boost.org/trac/boost/ticket/10771 Boost Trac #10771: ['remove_if is broken for slist]]
3942    *  [@https://svn.boost.org/trac/boost/ticket/10853 Boost Trac #10853: ['problem with detection of const_cast_from]]
3943    *  [@https://svn.boost.org/trac/boost/ticket/10987 Boost Trac #10987: ['bug in any_xxx_node_traits, returning by reference]]
3944
3945 [endsect]
3946
3947 [section:release_notes_boost_1_57_00 Boost 1.57 Release]
3948
3949 *  Experimental version of node checkers, contributed by Matei David. Many thanks!
3950 *  Implemented [@http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3644.pdf N3644: Null Forward Iterators] from C++14.
3951 *  Fixed bugs:
3952    *  [@https://github.com/boostorg/intrusive/pull/12 GitHub Pull #12: ['Fix MSVC14 warning C4456: declaration of 'x_parent_right' hides previous local declaration]]
3953    *  [@https://svn.boost.org/trac/boost/ticket/10520 Boost Trac #10520: ['Conversion warning in intrusive/detail/utilities.hpp]]
3954    *  [@https://svn.boost.org/trac/boost/ticket/10469 Boost Trac #10469: ['Erasing from intrusive unordered_multiset with optimize_multikey goes into an infinite loop]]
3955
3956 [endsect]
3957
3958 [section:release_notes_boost_1_56_00 Boost 1.56 Release]
3959
3960 *  Improved Doxygen generated reference and updated and fixed forward-declaration header.
3961
3962 *  [*ABI breaking]: Fixed ABI regression introduced in Boost 1.55 version, mainly noticeable on MSVC compilers.
3963
3964 *  [*Source breaking]: Removed previously deprecated `xxx_dont_splay` functions from splay containers,
3965    `splay_set_base_hook` and `splay_set_member_hook`from splay containers and `bool splay = true`
3966    extra parameter in `splaytree_algorithms` functions.
3967
3968 *  Fixed bugs:
3969    *  [@https://svn.boost.org/trac/boost/ticket/8468 #8468: Compile error on visual studio 2010/2012 using vector with custom allocator and aligned types]
3970    *  [@https://svn.boost.org/trac/boost/ticket/9332 #9332: ['"has_member_function_callable_with.hpp compile error on msvc-12.0"]].
3971    *  [@https://svn.boost.org/trac/boost/ticket/9650 #9650: ['"intrusive list with stateful value traits"]].
3972    *  [@https://svn.boost.org/trac/boost/ticket/9746 #9746: Modern Sun CC compiler detects error in intrusive library header]
3973    *  [@https://svn.boost.org/trac/boost/ticket/9940 #9940: bad bug in intrusive list with safe_link (or auto_unlink) hooks]
3974    *  [@https://svn.boost.org/trac/boost/ticket/9948 #9948: remove use of const_cast in intrusive containers]
3975    *  [@https://svn.boost.org/trac/boost/ticket/9949 #9949: clear header node hooks upon intrusive container destruction]
3976    *  [@https://svn.boost.org/trac/boost/ticket/9961 #9961: tests for hooks not derived frorm generic_hook]
3977
3978 *  Optimized tree rebalancing code to avoid redundant assignments.
3979
3980 *  Added 64 bit prime values for `suggested_upper_bucket_count`/`suggested_lower_bucket_count` in 64 bit platforms.
3981
3982 *  Deleted workarounds for old SUN_CC compilers, those are now unsupported as modern SunPro compilers are standard-corforming enough.
3983
3984 [endsect]
3985
3986 [section:release_notes_boost_1_55_00 Boost 1.55 Release]
3987
3988 *  [*Source breaking]: Deprecated `xxx_dont_splay` functions from splay containers.
3989    Deprecated `splay_set_base_hook` and `splay_set_member_hook`from splay containers, use
3990   `bs_set_base_hook` or `bs_set_member_hook` instead.
3991    Both will be removed in Boost 1.56.
3992
3993 *  [*ABI breaking]: Hash containers' end iterator was implemented pointing to one-past the end of the bucket array
3994    (see [@https://svn.boost.org/trac/boost/ticket/8698 #8698]) causing severe bugs when values to be inserted
3995    where allocated next to the bucket array. End iterator implementation was changed to point to the beginning
3996    of the bucket array.
3997
3998 *  Big refactoring in order to reduce template and debug symbol bloat. Test object files have been slashed
3999    to half in MSVC compilers in Debug mode. Toolchains without Identical COMDAT Folding (ICF) should notice size improvements.
4000
4001 *  Implemented [link intrusive.scary_iterators SCARY iterators].
4002
4003 [endsect]
4004
4005 [section:release_notes_boost_1_54_00 Boost 1.54 Release]
4006
4007 *  Added `BOOST_NO_EXCEPTIONS` support (bug [@https://svn.boost.org/trac/boost/ticket/7849 #7849]).
4008
4009 [endsect]
4010
4011 [section:release_notes_boost_1_53_00 Boost 1.53 Release]
4012
4013 *  Fixed bugs
4014    [@https://svn.boost.org/trac/boost/ticket/7174 #7174],
4015    [@https://svn.boost.org/trac/boost/ticket/7529 #7529],
4016    [@https://svn.boost.org/trac/boost/ticket/7815 #7815].
4017 *  Fixed GCC -Wshadow warnings.
4018 *  Added missing `explicit` keyword in several intrusive container constructors.
4019 *  Replaced deprecated BOOST_NO_XXXX with newer BOOST_NO_CXX11_XXX macros.
4020 *  Small documentation fixes.
4021
4022 [endsect]
4023
4024 [section:release_notes_boost_1_51_00 Boost 1.51 Release]
4025
4026 *  Fixed bugs
4027   [@https://svn.boost.org/trac/boost/ticket/6841 #6841],
4028   [@https://svn.boost.org/trac/boost/ticket/6907 #6907],
4029   [@https://svn.boost.org/trac/boost/ticket/6922 #6922],
4030   [@https://svn.boost.org/trac/boost/ticket/7033 #7033],
4031
4032 * Added `bounded_range` function to trees.
4033
4034 [endsect]
4035
4036 [section:release_notes_boost_1_49_00 Boost 1.49 Release]
4037
4038 *  Fixed bugs
4039   [@https://svn.boost.org/trac/boost/ticket/6347 #6347],
4040   [@https://svn.boost.org/trac/boost/ticket/6223 #6223],
4041   [@https://svn.boost.org/trac/boost/ticket/6153 #6153].
4042
4043
4044 [endsect]
4045
4046 [section:release_notes_boost_1_48_00 Boost 1.48 Release]
4047
4048 *  Fixed bugs
4049   [@https://svn.boost.org/trac/boost/ticket/4797 #4797],
4050   [@https://svn.boost.org/trac/boost/ticket/5165 #5165],
4051   [@https://svn.boost.org/trac/boost/ticket/5183 #5183],
4052   [@https://svn.boost.org/trac/boost/ticket/5191 #5191].
4053
4054 [endsect]
4055
4056 [section:release_notes_boost_1_46_00 Boost 1.46 Release]
4057
4058 *  Fixed bug
4059   [@https://svn.boost.org/trac/boost/ticket/4980 #4980],
4060
4061 [endsect]
4062
4063 [section:release_notes_boost_1_45_00 Boost 1.45 Release]
4064
4065 *  Added `function_hook` option.
4066 *  Fixed bugs
4067   [@https://svn.boost.org/trac/boost/ticket/2611 #2611],
4068   [@https://svn.boost.org/trac/boost/ticket/3288 #3288],
4069   [@https://svn.boost.org/trac/boost/ticket/3304 #3304],
4070   [@https://svn.boost.org/trac/boost/ticket/3489 #3489],
4071   [@https://svn.boost.org/trac/boost/ticket/3668 #3668],
4072   [@https://svn.boost.org/trac/boost/ticket/3339 #3688],
4073   [@https://svn.boost.org/trac/boost/ticket/3698 #3698],
4074   [@https://svn.boost.org/trac/boost/ticket/3706 #3706],
4075   [@https://svn.boost.org/trac/boost/ticket/3721 #3721].
4076   [@https://svn.boost.org/trac/boost/ticket/3729 #3729],
4077   [@https://svn.boost.org/trac/boost/ticket/3746 #3746],
4078   [@https://svn.boost.org/trac/boost/ticket/3781 #3781],
4079   [@https://svn.boost.org/trac/boost/ticket/3840 #3840],
4080   [@https://svn.boost.org/trac/boost/ticket/3849 #3849],
4081   [@https://svn.boost.org/trac/boost/ticket/3339 #3339],
4082   [@https://svn.boost.org/trac/boost/ticket/3419 #3419],
4083   [@https://svn.boost.org/trac/boost/ticket/3431 #3431],
4084   [@https://svn.boost.org/trac/boost/ticket/4021 #4021].
4085
4086 [endsect]
4087
4088
4089 [section:release_notes_boost_1_40_00 Boost 1.40 Release]
4090
4091 *  Code cleanup in bstree_algorithms.hpp and avl_tree_algorithms.hpp
4092 *  Fixed bug
4093   [@https://svn.boost.org/trac/boost/ticket/3164 #3164].
4094
4095 [endsect]
4096
4097
4098 [section:release_notes_boost_1_39_00 Boost 1.39 Release]
4099
4100 *  Optimized `list::merge` and `slist::merge`
4101 *  `list::sort` and `slist::sort` are now stable.
4102 *  Fixed bugs
4103   [@https://svn.boost.org/trac/boost/ticket/2689 #2689],
4104   [@https://svn.boost.org/trac/boost/ticket/2755 #2755],
4105   [@https://svn.boost.org/trac/boost/ticket/2786 #2786],
4106   [@https://svn.boost.org/trac/boost/ticket/2807 #2807],
4107   [@https://svn.boost.org/trac/boost/ticket/2810 #2810],
4108   [@https://svn.boost.org/trac/boost/ticket/2862 #2862].
4109
4110 [endsect]
4111
4112 [section:release_notes_boost_1_38_00 Boost 1.38 Release]
4113
4114 *  New treap-based containers: treap, treap_set, treap_multiset.
4115 *  Corrected compilation bug for Windows-based 64 bit compilers.
4116 *  Corrected exception-safety bugs in container constructors.
4117 *  Updated documentation to show rvalue-references functions instead of emulation functions.
4118
4119 [endsect]
4120
4121 [section:release_notes_boost_1_37_00 Boost 1.37 Release]
4122
4123 *  Intrusive now takes advantage of compilers with variadic templates.
4124 *  `clone_from` functions now copy predicates and hash functions of associative containers.
4125 *  Added incremental hashing to unordered containers via `incremental<>` option.
4126 *  Update some function parameters from `iterator` to `const_iterator` in containers
4127    to keep up with the draft of the next standard.
4128 *  Added an option to specify include files for intrusive configurable assertion macros.
4129
4130 [endsect]
4131
4132 [section:release_notes_boost_1_36_00 Boost 1.36 Release]
4133
4134 *  Added `linear<>` and `cache_last<>` options to singly linked lists.
4135 *  Added `optimize_multikey<>` option to unordered container hooks.
4136 *  Optimized unordered containers when `store_hash` option is used in the hook.
4137 *  Implementation changed to be exception agnostic so that it can be used
4138    in environments without exceptions.
4139 *  Added `container_from_iterator` function to tree-based containers.
4140
4141 [endsect]
4142
4143 [endsect]
4144
4145 [section:tested_compilers Tested compilers]
4146
4147 [*Boost.Intrusive] has been tested on the following compilers/platforms:
4148
4149 *  Visual >= 7.1
4150 *  GCC >= 4.1
4151 *  Intel 11
4152
4153 [endsect]
4154
4155 [section:references References]
4156
4157 * SGI's [@http://www.sgi.com/tech/stl/ STL Programmer's Guide].
4158    [*Boost.Intrusive] is based on STL concepts and interfaces.
4159
4160 * Dr. Dobb's, September 1, 2005: [@http://www.ddj.com/architect/184402007 ['Implementing Splay Trees in C++] ].
4161    [*Boost.Intrusive] splay containers code is based on this article.
4162
4163 * Olaf's original intrusive container library: [@http://freenet-homepage.de/turtle++/intrusive.html ['STL-like intrusive containers] ].
4164
4165 [endsect]
4166
4167 [section:acknowledgements Acknowledgements]
4168
4169 [*Olaf Krzikalla] would like to thank:
4170
4171 *  [*Markus Schaaf] for pointing out the possibility and the advantages of the derivation
4172 approach.
4173
4174 *  [*Udo Steinbach] for encouragements to present this work for boost, a lot of fixes and
4175 helpful discussions.
4176
4177 *  [*Jaap Suter] for the initial hint, which eventually lead to the member value_traits.
4178
4179 [*Ion Gaztanaga] would like to thank:
4180
4181 *  [*Olaf Krzikalla] for the permission to continue his great work.
4182
4183 *  [*Joaquin M. Lopez Munoz] for his thorough review, help, and ideas.
4184
4185 *  [*Cory Nelson], [*Daniel James], [*Dave Harris], [*Guillaume Melquiond],
4186    [*Henri Bavestrello], [*HervĂ© Bronnimann], [*Kai Bruning], [*Kevin Sopp],
4187    [*Paul Rose], [*Pavel Vozelinek], [*Howard Hinnant], [*Olaf Krzikalla],
4188    [*Samuel Debionne], [*Stjepan Rajko], [*Thorsten Ottosen], [*Tobias Schwinger],
4189    [*Tom Brinkman] and [*Steven Watanabe]
4190    for their comments and reviews in the Boost.Intrusive formal review.
4191
4192 *  Thanks to [*Julienne Walker] and [*The EC Team] ([@http://eternallyconfuzzled.com])
4193    for their great algorithms.
4194
4195 *  Thanks to [*Daniel K. O.] for his AVL tree rebalancing code.
4196
4197 *  Thanks to [*Ralf Mattethat] for his splay tree article and code.
4198
4199 *  Special thanks to [*Steven Watanabe] and [*Tobias Schwinger] for their
4200    invaluable suggestions and improvements.
4201
4202 [endsect]
4203
4204 [include auto_index_helpers.qbk]
4205
4206 [section:index Indexes]
4207
4208 [named_index class_name Class Index]
4209 [named_index typedef_name Typedef Index]
4210 [named_index function_name Function Index]
4211 [named_index macro_name Macro Index]
4212 [/index]
4213
4214 [endsect]
4215
4216 [xinclude autodoc.xml]