Skip to content

Commit 34bdb94

Browse files
committed
Add documentation chapter and example code for string options.
1 parent 11f13e8 commit 34bdb94

File tree

2 files changed

+111
-37
lines changed

2 files changed

+111
-37
lines changed

doc/container.qbk

Lines changed: 45 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
[library Boost.Container
99
[quickbook 1.7]
1010
[authors [Gaztanaga, Ion]]
11-
[copyright 2009-2018 Ion Gaztanaga]
11+
[copyright 2009-2026 Ion Gaztanaga]
1212
[id container]
1313
[dirname container]
1414
[purpose Containers library]
@@ -172,7 +172,7 @@ Finally C++17 added support for incomplete types in `std::vector`, `std::list` a
172172
for details), but no other containers like `std::set/map/unordered_set/unordered_map`,
173173

174174
Fortunately all [*Boost.Container] containers except
175-
[classref boost::container::static_vector static_vector] and
175+
[classref boost::container::static_vector static_vector],
176176
[classref boost::container::small_vector small_vector] and
177177
[classref boost::container::basic_string basic_string] are designed to support incomplete types.
178178
[classref boost::container::static_vector static_vector] and
@@ -734,19 +734,21 @@ the last template parameter and defined using the utility class
734734
[classref boost::container::vector_options vector_options]. The following parameters can be configured:
735735

736736
* [classref boost::container::growth_factor growth_factor]: the growth policy of the vector.
737-
The rate at which the capacity of a vector grows is implementation dependent and
738-
implementations choose exponential growth in order to meet the amortized constant time requirement for push_back.
737+
The rate at which the capacity grows is implementation dependent and
738+
implementations choose exponential growth in order to meet the amortized constant time requirements.
739739
A higher growth factor will make it faster as it will require less data movement, but it will have a greater memory
740740
impact (on average, more memory will be unused). A user can provide a custom implementation of the growth factor and some
741741
predefined policies are available: [classref boost::container::growth_factor_50 growth_factor_50],
742-
[classref boost::container::growth_factor_60 growth_factor_60] (usually the default) and
742+
[classref boost::container::growth_factor_60 growth_factor_60] (usually the default in Boost.Container) and
743743
[classref boost::container::growth_factor_100 growth_factor_100].
744744

745745
* [classref boost::container::stored_size stored_size]: the type that will be used to store size-related
746746
parameters inside the vector. Sometimes, when the maximum vector capacity to be used is much less than
747747
`std::size_t` capacity, it may be beneficial to use a smaller unsigned integer type to represent
748748
`size()` and `capacity()` values inside the vector, so that the size of an empty vector object is minimized and cache
749-
performance is possibly improved. See [classref boost::container::stored_size stored_size] for more details.
749+
performance is possibly improved. See [classref boost::container::stored_size stored_size] for more details. Note
750+
that due to alignment issues, using a unsigned type smaller than std::size_t to store size-related parameters might
751+
not bring any size gains and will severely limit the maximum size of the container.
750752

751753
See the following example to see how [classref boost::container::vector_options vector_options] can be
752754
used to customize `vector`:
@@ -771,10 +773,8 @@ the last template parameter and defined using the utility class
771773
does not throw or abort, undefined behavior is triggered.
772774

773775
* [classref boost::container::stored_size stored_size]: the type that will be used to store size-related
774-
parameters inside the vector. Sometimes, when the static size to be used is much less than `std::size_t` capacity,
775-
it may be beneficial to use a smaller unsigned integer type to represent the `size()` value inside `static_vector`,
776-
so that the object size of an empty vector is minimized and cache
777-
performance is possibly improved. See [classref boost::container::stored_size stored_size] for more details.
776+
parameters inside the vector. See `stored_size` option in [link container.configurable_containers.configurable_vector Configurable vector]
777+
chapter and [classref boost::container::stored_size stored_size] for more details.
778778

779779
See the following example to see how [classref boost::container::static_vector_options static_vector_options] can be
780780
used to customize `static_vector`:
@@ -795,19 +795,12 @@ the last template parameter and defined using the utility class
795795
and it is not affected by this option].
796796

797797
* [classref boost::container::growth_factor growth_factor]: the growth policy of the vector.
798-
The rate at which the capacity of a vector grows is implementation dependent and
799-
implementations choose exponential growth in order to meet the amortized constant time requirement for push_back.
800-
A higher growth factor will make it faster as it will require less data movement, but it will have a greater memory
801-
impact (on average, more memory will be unused). A user can provide a custom implementation of the growth factor and some
802-
predefined policies are available: [classref boost::container::growth_factor_50 growth_factor_50],
803-
[classref boost::container::growth_factor_60 growth_factor_60] and
804-
[classref boost::container::growth_factor_50 growth_factor_100].
798+
See `growth_factor` option in [link container.configurable_containers.configurable_vector Configurable vector]
799+
chapter and [classref boost::container::growth_factor growth_factor] for more details.
805800

806801
* [classref boost::container::stored_size stored_size]: the type that will be used to store size-related
807-
parameters inside the vector. Sometimes, when the maximum vector capacity to be used is much less than
808-
`std::size_t` capacity, it may be beneficial to use a smaller unsigned integer type to represent
809-
`size()` and `capacity()` values inside the vector, so that the size of an empty vector object is minimized and cache
810-
performance is possibly improved. See [classref boost::container::stored_size stored_size] for more details.
802+
parameters inside the vector. See `stored_size` option in [link container.configurable_containers.configurable_vector Configurable vector]
803+
chapter and [classref boost::container::stored_size stored_size] for more details.
811804

812805
See the following example to see how [classref boost::container::small_vector_options small_vector_options] can be
813806
used to customize `small_vector`:
@@ -835,10 +828,8 @@ Only one of these paratemers can be specified:
835828
A value of zero means the default value.
836829

837830
* [classref boost::container::stored_size stored_size]: the type that will be used to store size-related
838-
parameters inside the deque. Sometimes, when the maximum deque capacity to be used is much less than
839-
`std::size_t` capacity, it may be beneficial to use a smaller unsigned integer type to represent
840-
positions and offsets inside the deque, so that the size of an empty deque object is minimized and cache
841-
performance is possibly improved. See [classref boost::container::stored_size stored_size] for more details.
831+
parameters inside the vector. See `stored_size` option in [link container.configurable_containers.configurable_vector Configurable vector]
832+
chapter and [classref boost::container::stored_size stored_size] for more details.
842833

843834

844835
See the following example to see how [classref boost::container::deque_options deque_options] can be
@@ -855,20 +846,13 @@ The configuration for [classref boost::container::devector devector] is passed a
855846
the last template parameter and defined using the utility class
856847
[classref boost::container::devector_options devector_options]. The following parameters can be configured:
857848

858-
* [classref boost::container::growth_factor growth_factor]: the growth policy of the devector.
859-
The rate at which the capacity of a devector grows is implementation dependent and
860-
implementations choose exponential growth in order to meet the amortized constant time requirement for push_back.
861-
A higher growth factor will make it faster as it will require less data movement, but it will have a greater memory
862-
impact (on average, more memory will be unused). A user can provide a custom implementation of the growth factor and some
863-
predefined policies are available: [classref boost::container::growth_factor_50 growth_factor_50],
864-
[classref boost::container::growth_factor_60 growth_factor_60] (usually the default) and
865-
[classref boost::container::growth_factor_100 growth_factor_100].
849+
* [classref boost::container::growth_factor growth_factor]: the growth policy of the vector.
850+
See `growth_factor` option in [link container.configurable_containers.configurable_vector Configurable vector]
851+
chapter and [classref boost::container::growth_factor growth_factor] for more details.
866852

867853
* [classref boost::container::stored_size stored_size]: the type that will be used to store size-related
868-
parameters inside of the devector. Sometimes, when the maximum devector capacity to be used is much less than
869-
`std::size_t` capacity, it may be beneficial to use a smaller unsigned integer type to represent
870-
`size()` and `capacity()` values inside the devector, so that the size of an empty devector object is minimized and cache
871-
performance is possibly improved. See [classref boost::container::stored_size stored_size] for more details.
854+
parameters inside the vector. See `stored_size` option in [link container.configurable_containers.configurable_vector Configurable vector]
855+
chapter and [classref boost::container::stored_size stored_size] for more details.
872856

873857
* [classref boost::container::relocate_on_66 relocate_on_XX]: load factor limit that will determine if
874858
new memory should be allocated or elements should relocated inside existing memory, when the free space
@@ -882,6 +866,30 @@ used to customize `devector`:
882866

883867
[endsect]
884868

869+
[section:configurable_string Configurable basic_string]
870+
871+
The configuration for [classref boost::container::basic_string basic_string] is passed as
872+
the last template parameter and defined using the utility class
873+
[classref boost::container::string_options string_options]. The following parameters can be configured:
874+
875+
* [classref boost::container::growth_factor growth_factor]: the growth policy of the vector.
876+
See `growth_factor` option in [link container.configurable_containers.configurable_vector Configurable vector]
877+
chapter and [classref boost::container::growth_factor growth_factor] for more details.
878+
879+
* [classref boost::container::stored_size stored_size]: the type that will be used to store size-related
880+
parameters inside the vector. See `stored_size` option in [link container.configurable_containers.configurable_vector Configurable vector]
881+
chapter and [classref boost::container::stored_size stored_size] for more details. Note that the internal
882+
small string optimization buffer might be reduced in size if a smaller than `std::size_t` `stored_size` unsigned
883+
type is used.
884+
885+
See the following example to see how [classref boost::container::string_options string_options] can be
886+
used to customize `string_options`:
887+
888+
[import ../example/doc_custom_string.cpp]
889+
[doc_custom_string]
890+
891+
[endsect]
892+
885893
[endsect]
886894

887895
[section:extended_allocators Extended functionality: Extended allocators]

example/doc_custom_string.cpp

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
//////////////////////////////////////////////////////////////////////////////
2+
//
3+
// (C) Copyright Ion Gaztanaga 2013-2013. Distributed under the Boost
4+
// Software License, Version 1.0. (See accompanying file
5+
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6+
//
7+
// See http://www.boost.org/libs/container for documentation.
8+
//
9+
//////////////////////////////////////////////////////////////////////////////
10+
//[doc_custom_string
11+
#include <boost/container/string.hpp>
12+
13+
//Make sure assertions are active
14+
#ifdef NDEBUG
15+
#undef NDEBUG
16+
#endif
17+
#include <cassert>
18+
19+
int main ()
20+
{
21+
using namespace boost::container;
22+
23+
//This option specifies that a string that will use "unsigned char" as
24+
//the type to store capacity or size internally.
25+
typedef string_options< stored_size<unsigned char> >::type size_option_t;
26+
27+
//Size-optimized string is smaller than the default one.
28+
typedef basic_string<char, std::char_traits<char>, void, size_option_t > size_optimized_string_t;
29+
assert(( sizeof(size_optimized_string_t) < sizeof(basic_string<char>) ));
30+
31+
//The internal small string optimization buffer is also smaller
32+
assert(( size_optimized_string_t().capacity() < basic_string<char>().capacity() ));
33+
34+
//Requesting capacity for more elements than representable by half of the
35+
//"unsigned char" max (due to the need to a bit to indicate short/long representation)
36+
//minus 1 (due to the terminating null) is an error in the size optimized string.
37+
bool exception_thrown = false;
38+
/*<-*/
39+
#ifndef BOOST_NO_EXCEPTIONS
40+
BOOST_CONTAINER_TRY{ size_optimized_string_t v(127, '\0');} BOOST_CONTAINER_CATCH(...) { exception_thrown = true; } BOOST_CONTAINER_CATCH_END
41+
#else
42+
exception_thrown = true;
43+
#endif //BOOST_NO_EXCEPTIONS
44+
/*->*/
45+
//=try { size_optimized_string_t v(127, '\0'); }
46+
//=catch(...){ exception_thrown = true; }
47+
48+
assert(exception_thrown == true);
49+
50+
//This option specifies that a string will increase its capacity 50%
51+
//each time the previous capacity was exhausted.
52+
typedef string_options< growth_factor<growth_factor_50> >::type growth_50_option_t;
53+
54+
//Fill the string until full capacity is reached
55+
basic_string<char, std::char_traits<char>, void, growth_50_option_t > growth_50_string(5, 0);
56+
const std::size_t old_cap = growth_50_string.capacity();
57+
growth_50_string.resize(old_cap);
58+
59+
//Now insert an additional item and check the new buffer is aproximately
60+
//50% bigger (rounding due to the null terminator might round down)
61+
growth_50_string.push_back(1);
62+
assert(growth_50_string.capacity() == old_cap*3/2);
63+
64+
return 0;
65+
}
66+
//]

0 commit comments

Comments
 (0)