Ticket #1912: intrusive.qbk.patch

File intrusive.qbk.patch, 35.1 KB (added by Gordon Woodhull, 14 years ago)

patch to qbk file

Line 
1144c144
2< a size overhead for each allocation to store bookeeping information and a
3---
4> a size overhead for each allocation to store bookkeeping information and a
5163c163
6< In some situation intrusives containers offer a no-throw guarantee that can't be
7---
8> In some situations intrusive containers offer a no-throw guarantee that can't be
9171c171
10< memory managed is done with intrusive containers. Memory management usually is not a predicable
11---
12> memory management is done with intrusive containers. Memory management usually is not a predicable
13178c178
14< maintenance information needed by the container. Hence, whenever a certain type shall
15---
16> maintenance information needed by the container. Hence, whenever a certain type will
17183c183
18< * In intrusive containers you don't store a copy of an object, [*but they rather the original object
19---
20> * In intrusive containers you don't store a copy of an object, [*but rather the original object
21197,198c197,198
22< containers don't have allocation capabilities, these operations have no sense. However,
23< swapping can be used to implement move-capabilities. To ease the implementation of
24---
25> containers don't have allocation capabilities, these operations make no sense. However,
26> swapping can be used to implement move capabilities. To ease the implementation of
27203,204c203,204
28< * Analyzing thread-safety of a program that uses containers is harder with intrusive containers, becuase
29< the container might be modified indirectly without an explicitly call to a container member.
30---
31> * Analyzing the thread safety of a program that uses containers is harder with intrusive containers, because
32> the container might be modified indirectly without an explicit call to a container member.
33236,237c236,237
34< container. We will take a simple intrusive container, like an intrusive list
35< ([classref boost::intrusive::list boost::intrusive::list]) for the following
36---
37> container. We will take a simple intrusive container, the intrusive list
38> ([classref boost::intrusive::list boost::intrusive::list]), for the following
39315c315
40< Some options configured for the hook (the type of the pointers, link mode...)
41---
42> Some options configured for the hook (the type of the pointers, link mode, etc.)
43329c329
44< (for example, STL-like containers, use the `size_type` defined by their allocator).
45---
46> (for example, STL-like containers use the `size_type` defined by their allocator).
47431,432c431,432
48< You can insert the same object in several intrusive containers at the same time, just
49< using one hook for each container. This is a full example using base and member hooks:
50---
51> You can insert the same object in several intrusive containers at the same time,
52> using one hook per container. This is a full example using base and member hooks:
53459c459
54< issue and...
55---
56> issue and:
57470c470
58< you have a vector of objects (say, `std::vector<Object>`) and you also have a list
59---
60> you have a vector of objects (say, `std::vector<Object>`), and you also have a list
61472c472
62< from the list iterator (`std::list<Object*>::iterator`) needs two steps:
63---
64> from the list iterator (`std::list<Object*>::iterator`) requires two steps:
65478,481c478,481
66< (vector's memory is guaranteed to be contiguous), and form something
67< like a data block, list nodes can stay dispersed in the heap memory.
68< Hence depending on your system you can get a lot of cache misses. The same doesn't hold
69< for an intrusive list. Indeed, dereferencing an an iterator from an intrusive list is performed in
70---
71> (a vector's memory is guaranteed to be contiguous), and form something
72> like a data block, list nodes may be dispersed in the heap memory.
73> Hence depending on your system you might get a lot of cache misses. The same doesn't hold
74> for an intrusive list. Indeed, dereferencing an iterator from an intrusive list is performed in
75487c487
76< in the same container as shown in the following example:
77---
78> in the same container, as shown in the following example:
79496c496
80< posible or desirable.
81---
82> possible or desirable.
83507,508c507,508
84< basic operations that can be applied to a groups of nodes. It's independent
85< from the node definition, and it's configured taking a NodeTraits template
86---
87> basic operations that can be applied to a group of nodes. It's independent
88> from the node definition and configured using a NodeTraits template
89510c510
90< [[Node Traits][A class that stores basic information and operations to insert a node in a group of nodes.]]
91---
92> [[Node Traits][A class that stores basic information and operations to insert a node into a group of nodes.]]
93531c531
94< * [*set/multiset/rbtree]: A `std::set/std::multiset` like intrusive associative containers
95---
96> * [*set/multiset/rbtree]: `std::set/std::multiset` like intrusive associative containers
97541c541
98< * [*splay_set/splay_multiset/splaytree]: A `std::set/std::multiset` like intrusive associative
99---
100> * [*splay_set/splay_multiset/splaytree]: `std::set/std::multiset` like intrusive associative
101549c549
102< balance factor to achieve the desised rebalancing frequency/search time compromise.
103---
104> balance factor to achieve the desired rebalancing frequency/search time compromise.
105555c555
106< * [*unordered_set/unordered_multiset]: A `std::tr1::unordered_set/std::tr1::unordered_multiset`
107---
108> * [*unordered_set/unordered_multiset]: `std::tr1::unordered_set/std::tr1::unordered_multiset`
109558c558
110< Many operations have an amortized constant time complexity.
111---
112> Many operations have amortized constant time complexity.
113563,564c563,564
114< * [*Linear time size]: The intrusive container doesn't hold a size member that it's
115< updated with every insertion/erasure. This implies that the `size()` function has not constant
116---
117> * [*Linear time size]: The intrusive container doesn't hold a size member that is
118> updated with every insertion/erasure. This implies that the `size()` function doesn't have constant
119566c566
120< `splice()` taking a range of iterators in linked lists have constant time complexity
121---
122> `splice()` taking a range of iterators in linked lists, have constant time complexity
123569c569
124< * [*Constant time size]: The intrusive container holds a size member that it's updated
125---
126> * [*Constant time size]: The intrusive container holds a size member that is updated
127588c588
128< and can convert some constant time operations in linear time operations.
129---
130> and can convert some constant time operations to linear time operations.
131592c592
132< having any reference to the container.
133---
134> referring to the container.
135596c596
136< be configured to use any type of pointers. This configuration information is also
137---
138> be configured to use any type of pointer. This configuration information is also
139614c614
140< //Configuring explicity the safe mode
141---
142> //Configuring the safe mode explicitly
143618,619c618,619
144< Thanks to the safe-mode the user can detect without any external reference, if the object
145< is actually inserted in a container. Let's review the basic features of the safe-mode:
146---
147> With the safe mode the user can detect if the object
148> is actually inserted in a container without any external reference. Let's review the basic features of the safe mode:
149621c621
150< * Hooks' constructor puts the hook in a well-known default state.
151---
152> * Hook's constructor puts the hook in a well-known default state.
153623c623
154< * Hooks' destructor checks if the hook is in the well-known default state. If not,
155---
156> * Hook's destructor checks if the hook is in the well-known default state. If not,
157626c626
158< * Every time an object is being inserted in the intrusive container, the container
159---
160> * Every time an object is inserted in the intrusive container, the container
161634c634
162< has been inserted in a container calling the `is_linked()` member function.
163---
164> has been inserted in a container by calling the `is_linked()` member function.
165636c636
166< in a container, the hook is in the default state and if it's inserted in a container, the
167---
168> in a container, the hook is in the default state, and if it is inserted in a container, the
169658c658
170< If any of these macros is not redefined, the assertion will be defaul to `BOOST_ASSERT`.
171---
172> If any of these macros is not redefined, the assertion will default to `BOOST_ASSERT`.
173673,674c673,674
174< node from the container at any moment, without having any reference to the container,
175< if the user want to do so.
176---
177> node from the container at any time, without having any reference to the container,
178> if the user wants to do so.
179676c676
180< These hooks have exactly the same size overhead as their analogue non auto-unlinking
181---
182> These hooks have exactly the same size overhead as their analog non auto-unlinking
183683c683
184< without using any reference to the container.
185---
186> without referring to the container.
187699,700c699,700
188< * Every time an object is being inserted in the intrusive container, the container
189< checks if the hook is the well-known default state. If not,
190---
191> * Every time an object is inserted in the intrusive container, the container
192> checks if the hook is in the well-known default state. If not,
193703c703
194< * Every time an object is being erased from the intrusive container, the container
195---
196> * Every time an object is erased from an intrusive container, the container
197766,768c766,768
198< that imposes is 1 pointer per node. The size of an empty, non constant-time size
199< [classref boost::intrusive::slist slist], is the size of 1 pointer. This
200< lightweight memory overhead comes with its drawbacks, though: many operations have
201---
202> it imposes is 1 pointer per node. The size of an empty, non constant-time size
203> [classref boost::intrusive::slist slist] is the size of 1 pointer. This
204> lightweight memory overhead comes with drawbacks, though: many operations have
205776c776
206< constructing more elaborated containers, singly linked lists are essential
207---
208> constructing more elaborate containers, singly linked lists are essential
209834,835c834,835
210< to configure the container (to know about value traits go to the section
211< titled [link intrusive.value_traits Containers with custom ValueTraits].
212---
213> to configure the container. (To learn about value traits go to the section
214> [link intrusive.value_traits Containers with custom ValueTraits].)
215875,876c875,876
216< that imposes is 2 pointers per node. An empty, non constant-time size [classref boost::intrusive::list list]
217< has also the size of 2 pointers. [classref boost::intrusive::list list]
218---
219> it imposes is 2 pointers per node. An empty, non constant-time size [classref boost::intrusive::list list]
220> also has the size of 2 pointers. [classref boost::intrusive::list list]
221878c878
222< and provides bidirectional iterator. It's recommendable to use use
223---
224> and provides a bidirectional iterator. It is recommended to use
225936,937c936,937
226< to configure the container (to know about value traits go to the section
227< titled [link intrusive.value_traits Containers with custom ValueTraits].
228---
229> to configure the container. (To learn about value traits go to the section
230> [link intrusive.value_traits Containers with custom ValueTraits].)
231977c977
232< searches, insertions, erasures, etc... [classref boost::intrusive::set set] and
233---
234> searches, insertions, erasures, etc. [classref boost::intrusive::set set] and
2351059,1060c1059,1060
236< to configure the container (to know about value traits go to the section
237< titled [link intrusive.value_traits Containers with custom ValueTraits].
238---
239> to configure the container. (To learn about value traits go to the section
240> [link intrusive.value_traits Containers with custom ValueTraits].)
2411244,1245c1244,1245
242< to configure the container (to know about value traits go to the section
243< titled [link intrusive.value_traits Containers with custom ValueTraits].
244---
245> to configure the container. (To learn about value traits go to the section
246> [link intrusive.value_traits Containers with custom ValueTraits].)
2471327c1327
248< Splay trees are self-adjusting binary search trees used tipically in caches, memory
249---
250> Splay trees are self-adjusting binary search trees used typically in caches, memory
2511329c1329
252< accessed elements have better access times that elements accessed less frequently.
253---
254> accessed elements have better access times than elements accessed less frequently.
2551341c1341
256< An empty, non constant-time size splay container has also the size of 3 pointers.
257---
258> An empty, non constant-time size splay container has also a size of 3 pointers.
2591346c1346
260< operations like searches, insertions, erasures, etc... but if some elements are
261---
262> operations like searches, insertions, erasures, etc., but if some elements are
2631353c1353
264< `count()`...
265---
266> `count()`, etc.
2671426,1427c1426,1427
268< to configure the container (to know about value traits go to the section
269< titled [link intrusive.value_traits Containers with custom ValueTraits].
270---
271> to configure the container. (To learn about value traits go to the section
272> [link intrusive.value_traits Containers with custom ValueTraits].)
2731451c1451
274< [classref boost::intrusive::sg_multiset sg_multiset] so a programmer
275---
276> [classref boost::intrusive::sg_multiset sg_multiset]. A programmer
2771453,1454c1453,1454
278< can be introduced in some situations in an splay container but that
279< can also be introduced in other compatible containers as well when
280---
281> can be inserted in some situations in an splay container but
282> also inserted in other compatible containers when
2831482c1482
284< and because red-black trees also take O(log n) time for the basic operations.
285---
286> and because both take O(log n) time for basic operations.
2871503c1503
288< has also the size of 3 pointers and an integer (3 pointers when optimized for size).
289---
290> also has a size of 3 pointers and an integer (3 pointers when optimized for size).
2911574,1575c1574,1575
292< to configure the container (to know about value traits go to the section
293< titled [link intrusive.value_traits Containers with custom ValueTraits].
294---
295> to configure the container. (To learn about value traits go to the section
296> [link intrusive.value_traits Containers with custom ValueTraits].)
2971725,1726c1725,1726
298< to configure the container (to know about value traits go to the section
299< titled [link intrusive.value_traits Containers with custom ValueTraits].
300---
301> to configure the container. (To learn about value traits go to the section
302> [link intrusive.value_traits Containers with custom ValueTraits].)
3031789c1789
304< like `equal_range`, `lower_bound`, `upper_bound`...
305---
306> like `equal_range`, `lower_bound`, `upper_bound`, etc.
3071791c1791
308< However, sometimes the object to be searched it's quite expensive to construct:
309---
310> However, sometimes the object to be searched is quite expensive to construct:
3111808c1808
312< [*have enough information to find the object]. In this case, a name it's enough
313---
314> [*have enough information to find the object]. In this case, a name is enough
3151865c1865
316< * if the insertion is possible (there is no equivalent value) collects all the needed information
317---
318> * if the insertion is possible (there is no equivalent value) `insert_check` collects all the needed information
3191874c1874
320< `insert_check` and `insert_commit` will come handy
321---
322> `insert_check` and `insert_commit` will come in handy
3231920c1920
324< will call "disposer" function object for every removed element. [classref boost::intrusive::list list] offers
325---
326> will call the "disposer" function object for every removed element. [classref boost::intrusive::list list] offers
3271922c1922
328< `remove_and_dispose`...
329---
330> `remove_and_dispose`, etc.
3311949c1949
332< Apart from the container to be cloned, `clone_from` takes two function objects as arguments. For example, the
333---
334> Apart from the container to be cloned, `clone_from` takes two function objects as arguments. For example, consider the
3351968,1969c1968,1969
336< * First clears and disposes all the elements from *this using the disposer function object.
337< * After that starts cloning all the elements of the source container using the cloner function object.
338---
339> * First it clears and disposes all the elements from *this using the disposer function object.
340> * After that it starts cloning all the elements of the source container using the cloner function object.
3412001c2001
342< Not every smart pointer is compatible with [*Boost.Intrusive], the smart pointer must
343---
344> Not every smart pointer is compatible with [*Boost.Intrusive]; the smart pointer must
3452011c2011
346< ADL. For example, for `boost::interprocess::offset_ptr` `detail::get_pointer` is defined
347---
348> ADL. For example, for `boost::interprocess::offset_ptr`, `detail::get_pointer` is defined
3492059,2060c2059,2060
350< explained in the [link intrusive.value_traits.stateful_value_traits Stateful value traits] section,
351< but the programmer uses hooks provided by [*Boost.Intrusive], those functions
352---
353> explained in the [link intrusive.value_traits.stateful_value_traits Stateful value traits] section;
354> if the programmer uses hooks provided by [*Boost.Intrusive], those functions
3552078c2078
356< unlink a node from another group of nodes... For example, a circular
357---
358> unlink a node from another group of nodes, etc. For example, a circular
3592082c2082
360< the needed interface. As an example, here is a class that implements algorithms
361---
362> the needed interface. As an example, here is a class that implements operations7'
3632119,2123c2119,2123
364< operations on a node that forms a group of nodes:
365< the type of the node, a function to obtain the pointer to the next node...
366< [*Node Traits] are the configuration information [*Node Algorithms]
367< need. Each type of [*Node Algorithms] expects an interface that compatible
368< [*Node Traits] must implement.
369---
370> operations on a node within a group of nodes:
371> the type of the node, a function to obtain the pointer to the next node, etc.
372> [*Node Traits] specify the configuration information [*Node Algorithms]
373> need. Each type of [*Node Algorithm] expects an interface that compatible
374> [*Node Traits] classes must implement.
3752152c2152
376< contains a node object, that will be used to form the group of nodes:
377---
378> contains a node object that will be used to form the group of nodes:
3792192c2192
380< value types that use different hooks. An intrusive container is also more elaborated
381---
382> value types that use different hooks. An intrusive container is also more elaborate
3832194c2194
384< size information, it can offer debugging facilities...
385---
386> size information, it can offer debugging facilities, etc.
3872386c2386
388< the pointers to the left and right nodes to itself and whose color is red.
389---
390> the left and right node pointers point to itself, and whose color is red.
3912457c2457
392< the pointers to the left and right nodes to itself.
393---
394> and whose left and right nodes pointers point to itself.
3952641c2641
396< `ValueTraits` also store information about the link policy of the values to be inserted.
397---
398> `ValueTraits` also stores information about the link policy of the values to be inserted.
3992655c2655
400< `ValueTraits` have the following interface:
401---
402> `ValueTraits` has the following interface:
4032681c2681
404< * [*['node_traits]]: The node configuration that it's needed by node algorithms.
405---
406> * [*['node_traits]]: The node configuration that is needed by node algorithms.
4072683c2683
408< described in the previous chapter: [link intrusive.node_algorithms Nodes Algorithms].
409---
410> described in the previous chapter: [link intrusive.node_algorithms Node Algorithms].
4112711c2711
412< as `node_ptr`: If `node_ptr` is `node *` `pointer` must be `value_type*`. If
413---
414> as `node_ptr`: If `node_ptr` is `node*`, `pointer` must be `value_type*`. If
4152717c2717
416< as `node_ptr`: If `node_ptr` is `node *` `const_pointer` must be `const value_type*`. If
417---
418> as `node_ptr`: If `node_ptr` is `node*`, `const_pointer` must be `const value_type*`. If
4192727c2727
420< as the link, containers
421---
422> as the link mode, containers
4232731d2730
424< normal_link,
4252733,2735c2732,2734
426< * [*`safe_link`]: If this linking policy is specified in a `ValueTraits` class
427< as the link, containers
428< configured with such `ValueTraits` will set the hooks
429---
430> * [*`safe_link`]: If this linking policy is specified as the link mode
431> in a `ValueTraits` class, containers
432> configured with this `ValueTraits` will set the hooks
4332742c2741
434< Containers also know that the a value can be silently erased from
435---
436> Containers also know that a value can be silently erased from
4372747c2746
438< These function take a reference to a value_type and return a pointer to the node
439---
440> These functions take a reference to a value_type and return a pointer to the node
4412752c2751
442< These function take a pointer to a node and return a pointer to the value
443---
444> These functions take a pointer to a node and return a pointer to the value
4452764c2763
446< the object in a singly and doubly linked list at the same time.
447---
448> the object in both a singly and a doubly linked list at the same time.
4492776c2775
450< Defining a value traits class that just defines `value_type` as
451---
452> Defining a value traits class that simply defines `value_type` as
4532797c2796
454< if the user does not want to use provided [*Boost.Intrusive] facilities.
455---
456> if the user does not want to use the provided [*Boost.Intrusive] facilities.
4572817c2816
458< we'll define a templatized `ValueTraits` that will work for both types:
459---
460> a templatized `ValueTraits` that will work for both types:
4612828c2827
462< all the possible [classref boost::intrusive::list list] containers
463---
464> all possible [classref boost::intrusive::list list] containers
4652836c2835
466< The previous example can be further simplified using
467---
468> The previous example can be further simplified using the
4692872,2873c2871,2872
470< so that we can even separate nodes and values and [*avoid modifying types to insert nodes].
471< [*Boost.Intrusive] differentiates between stateful and stateless value traits checking if the ValueTraits
472---
473> so that we can separate nodes and values and [*avoid modifying types to insert nodes].
474> [*Boost.Intrusive] differentiates between stateful and stateless value traits by checking if the ValueTraits
4752883c2882
476< (stateless value traits could use global variables to achieve the same property), so:
477---
478> (stateless value traits could use global variables to achieve the same goal), so:
4792886,2887c2885,2886
480< value traits, since accessing to global resources might require syncronization primitives that
481< can be avoided when using the internal state.
482---
483> value traits, since accessing global resources might require syncronization primitives that
484> can be avoided when using internal state.
4852889c2888
486< * [*Run-time polimorphism]: A value traits might implement node <-> value
487---
488> * [*Run-time polymorphism]: A value traits might implement node <-> value
4892896c2895
490< [*A heavy node <-> value transformation can downgrade intrusive containers' performance].
491---
492> [*A heavy node <-> value transformation will hurt intrusive containers' performance].
4932917c2916
494< Intrusive containers have similar same thread-safety guarantees than STL containers.
495---
496> Intrusive containers have thread safety guarantees similar to STL containers.
4972919c2918
498< * Several threads can have read or write access to different instances is safe as long as inserted
499---
500> * Several threads having read or write access to different instances is safe as long as inserted
5012926,2927c2925,2926
502< Other functions, like checking if an objects is already inserted in a containers using the `is_linked()`
503< member of safe hooks is a read-access to the container without having a reference to them, so no other
504---
505> Other functions, like checking if an object is already inserted in a container using the `is_linked()`
506> member of safe hooks, constitute read access on the container without having a reference to it, so no other
5072931c2930
508< the thread safety of [*Boost.Intrusive] is related to the containers and also the object whose lifetime
509---
510> the thread safety of [*Boost.Intrusive] is related to the containers and also to the object whose lifetime
5112937c2936
512< To analyze the thread-safety, take in care the following points:
513---
514> To analyze the thread safety, consider the following points:
5152939,2941c2938,2940
516< * Auto-unlink hook's destructor and `unlink()` functions modify the container indirectly.
517< * Safe mode and auto-unlink hook's `is_linked()` function is a read access to the container.
518< * Inserting an object in several containers that will be modified by different threads has no thread-safety
519---
520> * The auto-unlink hook's destructor and `unlink()` functions modify the container indirectly.
521> * The safe mode and auto-unlink hooks' `is_linked()` functions are a read access to the container.
522> * Inserting an object in containers that will be modified by different threads has no thread safety
5232949c2948
524< has also a couple of downsides:
525---
526> has a couple of downsides:
5272951,2954c2950,2953
528< * If a user specifies the same options in different order or specifies some options and lefts the
529< rest as defaults the type of the created container/hook will be different. Sometimes
530< this is annoying, because two programmers specifying the same options might end with incompatible
531< types. For example, the following two lists, although they're using the same options, have not
532---
533> * If a user specifies the same options in different order or specifies some options and leaves the
534> rest as defaults, the type of the created container/hook will be different. Sometimes
535> this is annoying, because two programmers specifying the same options might end up with incompatible
536> types. For example, the following two lists, although using the same options, do not have
5372972c2971
538< might suffer a bit if long names are produced.
539---
540> may suffer if long names are produced.
5412974,2977c2973,2976
542< To solve these issues [*Boost.Intrusive] offers some helper metafunctions that that reduce symbol lengths
543< and create the same type if the same options (either explicitly or implicitly) are used. This also
544< improves compilation times. All containers and hooks have their respective `make_xxx` versions.
545< Previous shown example can be rewritten like this to obtain the same list type:
546---
547> To solve these issues [*Boost.Intrusive] offers some helper metafunctions that reduce symbol lengths
548> and create the same type if the same options (either explicitly or implicitly) are used. These also
549> improve compilation times. All containers and hooks have their respective `make_xxx` versions.
550> The previously shown example can be rewritten like this to obtain the same list type:
5512995,2996c2994,2995
552< Produced symbol lengths and compilation times are usually shorter and object/debug files are smaller.
553< If you are a programmer concerned with file sizes and compilation times, this option is your choice.
554---
555> Produced symbol lengths and compilation times will usually be shorter and object/debug files smaller.
556> If you are concerned with file sizes and compilation times, this option is your best choice.
5573025c3024
558< [*Boost.Intrusive] wants to avoid any code size overhead associated with templates.
559---
560> [*Boost.Intrusive] seeks to avoid any code size overhead associated with templates.
5613029,3030c3028,3029
562< are two-byte aligned. The possibility to avoid constant-time size operations can
563< save some size on containers, and this extra size optimization is noticeable
564---
565> are two-byte aligned. The option to forgo constant-time size operations can
566> reduce container size, and this extra size optimization is noticeable
5673035c3034
568< [section: Boost.Intrusive as basic building block]
569---
570> [section: Boost.Intrusive as a basic building block]
5713037,3039c3036,3038
572< [*Boost.Intrusive] should be a basic building block to build more complex containers
573< and this guideline has motivated many design decisions. For example, the possibility
574< to have more than one hook per user type opens the possibility to implement multi-index
575---
576> [*Boost.Intrusive] can be a basic building block to build more complex containers
577> and this potential has motivated many design decisions. For example, the ability
578> to have more than one hook per user type opens the opportunity to implement multi-index
5793043,3044c3042,3043
580< as arguments (`clone_from`, `erase_and_dispose`, `insert_check`...). These
581< functions come handy when implementing non-intrusive containers
582---
583> as arguments (`clone_from`, `erase_and_dispose`, `insert_check`, etc.). These
584> functions come in handy when implementing non-intrusive containers
5853054c3053
586< build special hooks that take advantage of its application environment.
587---
588> build special hooks that take advantage of an application environment.
5893056c3055
590< For example, the programmer can use can customize parts of [*Boost.Intrusive]
591---
592> For example, the programmer can customize parts of [*Boost.Intrusive]
5933065,3066c3064,3065
594< [*Boost.Intrusive] containers offer speed improvements comparing to non-intrusive containers,
595< basically because:
596---
597> [*Boost.Intrusive] containers offer speed improvements compared to non-intrusive containers
598> primarily because:
5993068,3069c3067,3068
600< * We can minimize memory allocation/deallocation calls.
601< * We obtain better memory locality.
602---
603> * They minimize memory allocation/deallocation calls.
604> * They obtain better memory locality.
6053071c3070
606< This section will show some performance tests comparing some operations on
607---
608> This section will show performance tests comparing some operations on
6093076c3075
610< * `reverse` member function will show the advantages of the compact
611---
612> * The `reverse` member function will show the advantages of the compact
6133078,3079c3077,3078
614< * `sort` and `write access` tests will show the advantage of intrusive containers
615< minimizing the memory accesses when comparing them with containers of pointers.
616---
617> * The `sort` and `write access` tests will show the advantage of intrusive containers
618> minimizing memory accesses compared to containers of pointers.
6193083c3082
620< or it can replace `std::list<T*>` when the user wants to obtain containers with
621---
622> or it can replace `std::list<T*>` when the user wants containers with
6233115c3114
624< `test_list` objects to funtion objects taking pointers to them.
625---
626> `test_list` objects to function objects taking pointers to them.
6273123c3122
628< avoiding memory allocations and deallocations . All the objects to be
629---
630> avoiding memory allocations and deallocations. All the objects to be
6313125c3124
632< whereas `std::list` will need to allocate memory for every and deallocate it
633---
634> whereas `std::list` will need to allocate memory for each object and deallocate it
6353183,3184c3182,3183
636< whereas `safe_link` and `auto_unlink` intrusive containers need to put the hook of
637< erased values' in the default state (complexity: `O(NumElements)`). That's why
638---
639> whereas `safe_link` and `auto_unlink` intrusive containers need to put the hooks of
640> erased values in the default state (complexity: `O(NumElements)`). That's why
6413187,3188c3186,3187
642< Non-intrusive containers need to make much more allocations and that's why they are
643< lagging behind. The `disperse pointer list` needs to make `NumElements*2` allocations,
644---
645> Non-intrusive containers need to make many more allocations and that's why they
646> lag behind. The `disperse pointer list` needs to make `NumElements*2` allocations,
6473191,3193c3190,3192
648< Linux test shows that standard containers perform very well against intrusive containers
649< with big objects. Nearly the same GCC version in MinGW performs worse, so maybe the
650< a good memory allocator is the reason for these excelent results.
651---
652> The Linux test shows that standard containers perform very well against intrusive containers
653> with big objects. Nearly the same GCC version in MinGW performs worse, so maybe
654> a good memory allocator is the reason for these excellent results.
6553200c3199
656< Values (`test_class` and `itest_class`) and lists are created like explained in the
657---
658> Values (`test_class` and `itest_class`) and lists are created as explained in the
6593205c3204
660< since this function just needs to adjust internal pointers, so in theory, all tested
661---
662> since this function just needs to adjust internal pointers, so in theory all tested
6633263,3265c3262,3264
664< For big values the compact pointer list wins because when reversing doesn't need access
665< to the values stored in another container. Since all the allocations for nodes of
666< this pointer list are likely to be near (since there is no other allocation in the
667---
668> For big objects the compact pointer list wins because the reversal test doesn't need access
669> to values stored in another container. Since all the allocations for nodes of
670> this pointer list are likely to be close (since there is no other allocation in the
6713267c3266
672< containers. The dispersed pointer list, like with small values, has poor locality.
673---
674> containers. The dispersed pointer list, as with small values, has poor locality.
6753273,3274c3272,3273
676< The next test measures the time needed to complete calls the member function
677< `sort(Pred pred)`. Values (`test_class` and `itest_class`) and lists are created like explained in the
678---
679> The next test measures the time needed to complete calls to the member function
680> `sort(Pred pred)`. Values (`test_class` and `itest_class`) and lists are created as explained in the
6813301c3300
682< another container to compare to elements.
683---
684> another container to compare two elements.
6853338,3341c3337,3340
686< indirection that needs to access the value is minimized because all the values
687< are tightly stored, improving cache. The disperse list, on the other hand, is
688< slower because the indirection to access to values stored in the object list is
689< more expensive than the access to values stored in a vector.
690---
691> indirection that is needed to access the value is minimized because all the values
692> are tightly stored, improving caching. The disperse list, on the other hand, is
693> slower because the indirection to access values stored in the object list is
694> more expensive than accessing values stored in a vector.
6953347c3346
696< The next test measures the time needed to iterate all the elements of a list, and
697---
698> The next test measures the time needed to iterate through all the elements of a list, and
6993356c3355
700< Values (`test_class` and `itest_class`) and lists are created like explained in
701---
702> Values (`test_class` and `itest_class`) and lists are created as explained in
7033399c3398
704< Like with the read access test, the results show that intrusive containers outperform
705---
706> As with the read access test, the results show that intrusive containers outperform
7073401c3400
708< The disperse list is again the slowest one.
709---
710> The disperse list is again the slowest.
7113409c3408
712< when objects to be inserted are small. Minimizing memory allocation/deallocation calls is also
713---
714> when the objects to be inserted are small. Minimizing memory allocation/deallocation calls is also
7153434c3433
716< [*Boost.Intrusive] has been tested in the following compilers/platforms:
717---
718> [*Boost.Intrusive] has been tested on the following compilers/platforms:
7193451c3450
720< [*Boost.Intrusive] is based on STL concepts and interface.
721---
722> [*Boost.Intrusive] is based on STL concepts and interfaces.
7233485c3484
724< * Thanks to of [*Julienne Walker] and [*The EC Team] ([@http://eternallyconfuzzled.com])
725---
726> * Thanks to [*Julienne Walker] and [*The EC Team] ([@http://eternallyconfuzzled.com])