75class character_range :
76 public ::block_range < ITERATOR_TYPE >
80 using THIS_CHARACTER_RANGE = character_range < ITERATOR_TYPE >;
81 using RAW_CHARACTER_RANGE = THIS_CHARACTER_RANGE;
83 using BASE_RANGE = ::character_range < ITERATOR_TYPE >;
84 using BASE_RAW_RANGE = ::block_range < ITERATOR_TYPE >;
85 using _BASE_RAW_RANGE = ::block_range < ITERATOR_TYPE >;
87 using this_iterator =
typename _BASE_RAW_RANGE::this_iterator;
89 using CHARACTER =
typename BASE_RANGE::ITEM;
90 using BASE_DATA = ::base_data < CHARACTER >;
92 BASE_DATA * m_pbasedata;
97 constexpr character_range() : _BASE_RAW_RANGE()
99 m_pbasedata =
nullptr;
102 constexpr character_range(nullptr_t) : _BASE_RAW_RANGE(
nullptr)
104 m_pbasedata =
nullptr;
107 template < typed_character_pointer < typename character_range < ITERATOR_TYPE >::CHARACTER > CHARACTER_POINTER >
108 character_range(CHARACTER_POINTER begin, CHARACTER_POINTER end, enum_range erange = e_range_none, BASE_DATA * pbasedata =
nullptr) :
109 _BASE_RAW_RANGE(begin, end, erange)
112 this->m_begin = begin;
114 this->m_pbasedata = pbasedata;
117 if (::is_set(this->m_pbasedata))
120 this->m_pbasedata->base_data_increment_reference_count();
127 template < other_character_pointer < typename character_range < ITERATOR_TYPE >::CHARACTER > OTHER_CHARACTER_POINTER >
128 character_range(OTHER_CHARACTER_POINTER start, OTHER_CHARACTER_POINTER end, enum_range erange = e_range_none) =
delete;
131 template <
character_count length >
132 character_range(
const CHARACTER (&s)[length]) :
136 auto lengthNew = string_safe_length2(s, length);
140 this->m_end = s + lengthNew;
142 this->m_erange = e_range_none;
144 this->m_pbasedata =
nullptr;
150 template <
character_po
inter CHARACTER_POINTER >
152 character_range(CHARACTER_POINTER start) : character_range(start, start + string_safe_length(start), e_range_none) { }
155 template <
character_po
inter CHARACTER_POINTER >
156 character_range(CHARACTER_POINTER start, character_count length) =
delete;
159 template < other_primitive_
character <CHARACTER> OTHER_CHARACTER,
character_count length >
160 character_range(
const CHARACTER(&s)[length]) =
delete;
163 character_range(
const character_range& characterrange) :
164 _BASE_RAW_RANGE(characterrange)
167 this->m_pbasedata = characterrange.m_pbasedata;
170 if (::is_set(this->m_pbasedata))
173 this->m_pbasedata->base_data_increment_reference_count();
179 character_range(character_range&& characterrange) :
180 _BASE_RAW_RANGE(::transfer(characterrange))
183 m_pbasedata = characterrange.m_pbasedata;
185 characterrange.m_pbasedata =
nullptr;
190 template <
typename TYPED_RANGE >
191 character_range(
const TYPED_RANGE& range)
requires
193 && !std::is_same_v<std::decay_t<TYPED_RANGE>, character_range>) :
194 character_range(range.m_begin, range.m_end, range.m_erange, range.m_pbasedata) { }
196 template <
typename OTHER_RANGE >
197 character_range(
const OTHER_RANGE& range)
requires
204 BASE_DATA * create_string_data2(character_count lengthNew, enum_range erange)
207 auto allocationSize = lengthNew;
209 if (erange & e_range_buffer)
216 auto pbasedata = BASE_DATA::create_base_data2(allocationSize + 1);
218 this->m_pbasedata = pbasedata;
220 this->m_erange = erange & ~e_range_string_literal;
227 inline memsize storage_count()
const
230 auto pbasedata = this->m_pbasedata;
232 if (is_null(pbasedata))
239 return pbasedata->storage_count();
244 inline character_count storage_character_count()
const
247 auto pbasedata = this->m_pbasedata;
249 if (is_null(pbasedata))
260 inline character_count length()
const {
return this->m_end - this->m_begin; }
261 inline character_count size()
const {
return this->length(); }
262 inline memsize character_count_in_bytes()
const {
return this->length() *
sizeof(CHARACTER); };
263 inline memsize null_terminated_character_count_in_bytes()
const {
return (this->length() + 1) *
sizeof(CHARACTER); }
265 character_range& operator=(
const character_range& range)
267 _BASE_RAW_RANGE::operator=(range);
268 this->m_pbasedata = range.m_pbasedata;
273 character_range& operator=(character_range&& range) {
274 _BASE_RAW_RANGE::operator=(::transfer(range));
275 this->m_pbasedata = range.m_pbasedata;
276 range.m_pbasedata =
nullptr;
295 constexpr bool has_string_storage()
const {
return m_pbasedata !=
nullptr; }
298 constexpr bool is_null_terminated()
const {
return !*this->m_end; }
301 constexpr bool is_working_string_range()
const {
return !this->has_string_storage(); }
307 _BASE_RAW_RANGE::set_null();
309 this->m_pbasedata =
nullptr;
323 void _set_length(::character_count count)
326 this->m_end = this->m_begin + count;
328 *((CHARACTER *)this->m_end) = {};
333 template <
typename SAME_ITERATOR_TYPE >
334 void construct_string(SAME_ITERATOR_TYPE start, SAME_ITERATOR_TYPE end, enum_range erange = e_range_none, typename ::character_range<SAME_ITERATOR_TYPE>::BASE_DATA * pbasedata =
nullptr)
335 requires (
sizeof(get_iterator_item < SAME_ITERATOR_TYPE >) ==
sizeof(CHARACTER))
338 auto length = end - start;
340 auto lengthNew = string_safe_length2(start, length);
342 if (::is_set(pbasedata))
345 if (pbasedata->data() != start || length > pbasedata->storage_character_count())
348 throw "wrong state in construct string (1)";
352 pbasedata->base_data_increment_reference_count();
354 this->m_pbasedata = pbasedata;
356 this->m_erange = erange;
358 this->m_begin = start;
364 auto pbasedata = this->create_string_data2(lengthNew, erange);
366 auto pdata = pbasedata->data();
368 this->m_begin = pdata;
370 memory_transfer(pdata, start, lengthNew);
374 this->_set_length(lengthNew);
379 template <
typename OTHER_ITERATOR_TYPE >
380 void construct_string(OTHER_ITERATOR_TYPE start, OTHER_ITERATOR_TYPE end, enum_range erange = e_range_none)
381 requires (
sizeof(get_iterator_item < OTHER_ITERATOR_TYPE >) !=
sizeof(CHARACTER))
384 auto srclen = end - start;
386 character_count lengthSrc = srclen;
388 auto lengthNew = utf_to_utf_length2(this->m_begin, start, lengthSrc);
390 auto pbasedata = this->create_string_data2(lengthNew, erange);
392 auto pdata = pbasedata->data();
394 this->m_begin = pdata;
396 utf_to_utf(pdata, start, lengthSrc);
398 this->_set_length(lengthNew);