I tried to study libstdc++ source code (GCC 7.2) recently and was confused. Probably I have missed something important, but I started to think that it is impossible to implement basic_string class that will fully comply C++ standard.
Here is a problem that I have faced.
Items 4 and 5 are conflicting and I don't know how to resolve it. Hope that you can help me to figure it out.
Thank you!
There are several requirements from the standard that together always ensure the conversion is possible, at least indirectly
Given basic_string<charT, traits, Allocator>
, the standard requires charT
and allocator_traits<Allocator>::value_type
be equal.
allocator_traits<Allocator>::pointer
is required to be either Allocator::pointer
or Allocator::value_type*
.
In the former case, given a Allocator::pointer
p
, *p
is required to be Allocator::value_type&
.
In the latter case, everything is trivial.
Allocator::pointer
is required to be a contiguous iterator, which requires, given a contiguous iterator q
, *(q + n) == *(addressof(*q) + n)
Given an Allocator
a
, a.allocate(n)
is required to return a Allocator::pointer
.
Combining everything together, it means this is always correct
template<typename charT, typename traits = /* ... */, typename Allocator = /* ... */>
class basic_string
{
typename std::allocator_traits<Allocator>::pointer _data;
// ...
public:
charT* c_str() { return std::addressof(*_data); }
// ...
};
Where _data
possibly stores the result from a previous call to Allocator::allocate