@@ -80,13 +80,14 @@ struct get_string_opt
8080{
8181 typedef string_opt< typename default_if_void<typename Options::growth_factor_type, growth_factor_60>::type
8282 , typename default_if_void<typename Options::stored_size_type, AllocatorSizeType>::type
83+ , Options::inline_chars
8384 > type;
8485};
8586
8687template <class AllocatorSizeType >
8788struct get_string_opt <void , AllocatorSizeType>
8889{
89- typedef string_opt<growth_factor_60, AllocatorSizeType> type;
90+ typedef string_opt<growth_factor_60, AllocatorSizeType, 0u > type;
9091};
9192
9293namespace dtl {
@@ -123,6 +124,8 @@ class basic_string_base
123124
124125 typedef ::boost::intrusive::pointer_traits<pointer> pointer_traits;
125126
127+ static const std::size_t inline_chars = options_type::inline_chars;
128+
126129 inline basic_string_base ()
127130 : members_()
128131 {}
@@ -209,24 +212,43 @@ class basic_string_base
209212
210213 // This type has the same alignment and size as long_t but it's POD
211214 // so, unlike long_t, it can be placed in a union
212-
213215 typedef typename dtl::aligned_storage
214216 <sizeof (long_t ), dtl::alignment_of<long_t >::value>::type long_raw_t ;
215217
218+ template <std::size_t NChar>
219+ union short_type_test
220+ {
221+ long_raw_t l;
222+ struct short_t
223+ {
224+ short_header h;
225+ value_type data[NChar+1u ];
226+ } s;
227+ };
228+
216229 protected:
217- BOOST_STATIC_CONSTEXPR size_type MinInternalBufferChars = 0 ;
218- BOOST_STATIC_CONSTEXPR size_type AlignmentOfValueType = alignment_of<value_type>::value;
219- BOOST_STATIC_CONSTEXPR size_type ShortDataOffset = ((sizeof (short_header)-1 )/AlignmentOfValueType+1 )*AlignmentOfValueType;
220- BOOST_STATIC_CONSTEXPR size_type ZeroCostInternalBufferChars =
221- (sizeof (long_t ) - ShortDataOffset)/sizeof (value_type);
222- BOOST_STATIC_CONSTEXPR size_type UnalignedFinalInternalBufferChars =
223- (ZeroCostInternalBufferChars > MinInternalBufferChars) ?
224- ZeroCostInternalBufferChars : MinInternalBufferChars;
230+ // Due to internal data representation constraints, inline chars cannot be bigger than this
231+ BOOST_STATIC_CONSTEXPR size_type MaxInlineChars = 127u ;
232+ BOOST_CONTAINER_STATIC_ASSERT (inline_chars <= MaxInlineChars);
233+
234+ BOOST_STATIC_CONSTEXPR size_type SizeOfValueType = sizeof (value_type);
235+ BOOST_STATIC_CONSTEXPR size_type ShortDataOffset = ((sizeof (short_header)-1 )/SizeOfValueType+1 )*SizeOfValueType;
236+ BOOST_STATIC_CONSTEXPR size_type ZeroCostInternalStorage = (sizeof (long_t ) - ShortDataOffset)/sizeof (value_type);
237+ BOOST_STATIC_CONSTEXPR size_type InlineCharsStorage = (sizeof (short_type_test<inline_chars>) - ShortDataOffset)/sizeof (value_type);
238+
239+ // Select the biggest internal buffer between zero-cost SSO and user-requested SSO
240+ BOOST_STATIC_CONSTEXPR size_type CandidateInternalStorageChars =
241+ ZeroCostInternalStorage > InlineCharsStorage ? ZeroCostInternalStorage : InlineCharsStorage;
242+
243+ // Clamp internal buffer chars to MaxInlineChars
244+ BOOST_STATIC_CONSTEXPR size_type MaxInlineStorage = MaxInlineChars+1u ;
245+ BOOST_STATIC_CONSTEXPR size_type FinalInternalStorage =
246+ CandidateInternalStorageChars < MaxInlineStorage ? CandidateInternalStorageChars : MaxInlineStorage;
225247
226248 struct short_t
227249 {
228250 short_header h;
229- value_type data[UnalignedFinalInternalBufferChars ];
251+ value_type data[FinalInternalStorage ];
230252 };
231253
232254 union repr_t_size_t
@@ -282,7 +304,7 @@ class basic_string_base
282304 inline allocator_type &alloc ()
283305 { return members_; }
284306
285- BOOST_STATIC_CONSTEXPR size_type InternalBufferChars = ( sizeof ( repr_t ) - ShortDataOffset)/ sizeof (value_type) ;
307+ BOOST_STATIC_CONSTEXPR size_type InternalBufferChars = FinalInternalStorage ;
286308
287309 private:
288310
@@ -581,6 +603,7 @@ class basic_string_base
581603// ! \tparam CharT The type of character it contains.
582604// ! \tparam Traits The Character Traits type, which encapsulates basic character operations
583605// ! \tparam Allocator The allocator, used for internal memory management.
606+ // ! \tparam Options A type produced from \c boost::container::string_options.
584607#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
585608template <class CharT , class Traits = std::char_traits<CharT>, class Allocator = void , class Options = void >
586609#else
0 commit comments