PMDK C++ bindings 1.13.0
This is the C++ bindings documentation for PMDK's libpmemobj.
inline_string.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSD-3-Clause
2/* Copyright 2020-2021, Intel Corporation */
3
9#ifndef LIBPMEMOBJ_CPP_INLINE_STRING_HPP
10#define LIBPMEMOBJ_CPP_INLINE_STRING_HPP
11
17
18#include <string>
19
20namespace pmem
21{
22
23namespace obj
24{
25
26namespace experimental
27{
28
29template <typename CharT, typename Traits = std::char_traits<CharT>>
30class basic_inline_string_base {
31public:
32 using traits_type = Traits;
33 using value_type = CharT;
34 using size_type = std::size_t;
35 using difference_type = std::ptrdiff_t;
36 using reference = value_type &;
37 using const_reference = const value_type &;
38 using pointer = value_type *;
39 using const_pointer = const value_type *;
40
41 basic_inline_string_base(basic_string_view<CharT, Traits> v);
42 basic_inline_string_base(size_type capacity);
43 basic_inline_string_base(const basic_inline_string_base &rhs);
44
45 basic_inline_string_base &
46 operator=(const basic_inline_string_base &rhs);
47
48 basic_inline_string_base &
49 operator=(basic_string_view<CharT, Traits> rhs);
50
51 basic_inline_string_base(basic_inline_string_base<CharT> &&) = delete;
52
53 basic_inline_string_base &
54 operator=(basic_inline_string_base &&) = delete;
55 operator basic_string_view<CharT, Traits>() const;
56
57 size_type size() const noexcept;
58 size_type capacity() const noexcept;
59
60 pointer data();
61 const_pointer data() const noexcept;
62 const_pointer cdata() const noexcept;
63
64 int compare(basic_string_view<CharT, Traits> rhs) const noexcept;
65
66 reference operator[](size_type p);
67 const_reference operator[](size_type p) const noexcept;
68
69 reference at(size_type p);
70 const_reference at(size_type p) const;
71
72 slice<pointer> range(size_type p, size_type count);
73
74 basic_inline_string_base &assign(basic_string_view<CharT, Traits> rhs);
75
76protected:
77 pointer snapshotted_data(size_t p, size_t n);
78
79 obj::p<uint64_t> size_;
80 obj::p<uint64_t> capacity_;
81};
82
100template <typename CharT, typename Traits = std::char_traits<CharT>>
102 : public basic_inline_string_base<CharT, Traits> {
103public:
104 using traits_type = Traits;
105 using value_type = CharT;
106 using size_type = std::size_t;
107 using difference_type = std::ptrdiff_t;
108 using reference = value_type &;
109 using const_reference = const value_type &;
110 using pointer = value_type *;
111 using const_pointer = const value_type *;
112 using basic_inline_string_base<CharT, Traits>::operator=;
113
115 : basic_inline_string_base<CharT, Traits>(v)
116 {
117 }
118
119 basic_dram_inline_string(size_type capacity)
120 : basic_inline_string_base<CharT, Traits>(capacity)
121 {
122 }
124 : basic_inline_string_base<CharT, Traits>(rhs)
125 {
126 }
127
129 operator=(const basic_dram_inline_string &rhs)
130 {
131 return static_cast<basic_dram_inline_string &>(this->operator=(
132 static_cast<const basic_inline_string_base<
133 CharT, Traits> &>(rhs)));
134 }
135};
136
153template <typename CharT, typename Traits = std::char_traits<CharT>>
154class basic_inline_string : public basic_inline_string_base<CharT, Traits> {
155public:
156 using traits_type = Traits;
157 using value_type = CharT;
158 using size_type = std::size_t;
159 using difference_type = std::ptrdiff_t;
160 using reference = value_type &;
161 using const_reference = const value_type &;
162 using pointer = value_type *;
163 using const_pointer = const value_type *;
164 using basic_inline_string_base<CharT, Traits>::operator=;
165
170 : basic_inline_string_base<CharT, Traits>(check_forward(v))
171 {
172 }
173
177 basic_inline_string(size_type capacity)
178 : basic_inline_string_base<CharT, Traits>(check_forward(capacity))
179 {
180 }
181
186 : basic_inline_string_base<CharT, Traits>(check_forward(rhs))
187 {
188 }
189
191 operator=(const basic_inline_string &rhs)
192 {
193 return static_cast<basic_inline_string &>(this->operator=(
194 static_cast<const basic_inline_string_base<
195 CharT, Traits> &>(rhs)));
196 }
197
198private:
199 template <typename T>
200 T &&
201 check_forward(T &&t)
202 {
203 if (nullptr == pmemobj_pool_by_ptr(this))
204 throw pmem::pool_error("Invalid pool handle.");
205 return std::forward<T>(t);
206 }
207};
208
209using dram_inline_string = basic_dram_inline_string<char>;
210using dram_inline_wstring = basic_dram_inline_string<wchar_t>;
211using dram_inline_u16string = basic_dram_inline_string<char16_t>;
212using dram_inline_u32string = basic_dram_inline_string<char32_t>;
213
214using inline_string = basic_inline_string<char>;
215using inline_wstring = basic_inline_string<wchar_t>;
216using inline_u16string = basic_inline_string<char16_t>;
217using inline_u32string = basic_inline_string<char32_t>;
218
222template <typename CharT, typename Traits>
223basic_inline_string_base<CharT, Traits>::basic_inline_string_base(
224 basic_string_view<CharT, Traits> v)
225 : size_(v.size()), capacity_(v.size())
226{
227 std::copy(v.data(), v.data() + static_cast<ptrdiff_t>(size_), data());
228
229 data()[static_cast<ptrdiff_t>(size_)] = '\0';
230}
231
235template <typename CharT, typename Traits>
236basic_inline_string_base<CharT, Traits>::basic_inline_string_base(
237 size_type capacity)
238 : size_(0), capacity_(capacity)
239{
240 data()[static_cast<ptrdiff_t>(size_)] = '\0';
241}
242
246template <typename CharT, typename Traits>
247basic_inline_string_base<CharT, Traits>::basic_inline_string_base(
248 const basic_inline_string_base &rhs)
249 : size_(rhs.size()), capacity_(rhs.capacity())
250{
251 std::copy(rhs.data(), rhs.data() + static_cast<ptrdiff_t>(size_),
252 data());
253
254 data()[static_cast<ptrdiff_t>(size_)] = '\0';
255}
256
260template <typename CharT, typename Traits>
261basic_inline_string_base<CharT, Traits> &
262basic_inline_string_base<CharT, Traits>::operator=(
263 const basic_inline_string_base &rhs)
264{
265 if (this == &rhs)
266 return *this;
267
268 return assign(rhs);
269}
270
274template <typename CharT, typename Traits>
275basic_inline_string_base<CharT, Traits> &
276basic_inline_string_base<CharT, Traits>::operator=(
277 basic_string_view<CharT, Traits> rhs)
278{
279 return assign(rhs);
280}
281
283template <typename CharT, typename Traits>
284basic_inline_string_base<CharT, Traits>::operator basic_string_view<
285 CharT, Traits>() const
286{
287 return {data(), size()};
288}
289
291template <typename CharT, typename Traits>
292typename basic_inline_string_base<CharT, Traits>::size_type
293basic_inline_string_base<CharT, Traits>::size() const noexcept
294{
295 return size_;
296}
297
305template <typename CharT, typename Traits>
306typename basic_inline_string_base<CharT, Traits>::size_type
307basic_inline_string_base<CharT, Traits>::capacity() const noexcept
308{
309 return capacity_;
310}
311
321template <typename CharT, typename Traits>
322typename basic_inline_string_base<CharT, Traits>::pointer
323basic_inline_string_base<CharT, Traits>::data()
324{
325 return snapshotted_data(0, size_);
326}
327
329template <typename CharT, typename Traits>
330typename basic_inline_string_base<CharT, Traits>::const_pointer
331basic_inline_string_base<CharT, Traits>::data() const noexcept
332{
333 return cdata();
334}
335
343template <typename CharT, typename Traits>
344typename basic_inline_string_base<CharT, Traits>::const_pointer
345basic_inline_string_base<CharT, Traits>::cdata() const noexcept
346{
347 return reinterpret_cast<const CharT *>(this + 1);
348}
349
358template <typename CharT, typename Traits>
359int
360basic_inline_string_base<CharT, Traits>::compare(
361 basic_string_view<CharT, Traits> rhs) const noexcept
362{
363 return basic_string_view<CharT, Traits>(data(), size()).compare(rhs);
364}
365
374template <typename CharT, typename Traits>
375typename basic_inline_string_base<CharT, Traits>::reference
376 basic_inline_string_base<CharT, Traits>::operator[](size_type p)
377{
378 return snapshotted_data(p, 1)[0];
379}
380
387template <typename CharT, typename Traits>
388typename basic_inline_string_base<CharT, Traits>::const_reference
389 basic_inline_string_base<CharT, Traits>::operator[](size_type p) const
390 noexcept
391{
392 return cdata()[p];
393}
394
404template <typename CharT, typename Traits>
405typename basic_inline_string_base<CharT, Traits>::reference
406basic_inline_string_base<CharT, Traits>::at(size_type p)
407{
408 if (p >= size())
409 throw std::out_of_range("basic_inline_string_base::at");
410
411 return snapshotted_data(p, 1)[0];
412}
413
422template <typename CharT, typename Traits>
423typename basic_inline_string_base<CharT, Traits>::const_reference
424basic_inline_string_base<CharT, Traits>::at(size_type p) const
425{
426 if (p >= size())
427 throw std::out_of_range("basic_inline_string_base::at");
428
429 return cdata()[p];
430}
431
445template <typename CharT, typename Traits>
446slice<typename basic_inline_string_base<CharT, Traits>::pointer>
447basic_inline_string_base<CharT, Traits>::range(size_type start, size_type n)
448{
449 if (start + n > size())
450 throw std::out_of_range("basic_inline_string_base::range");
451
452 auto data = snapshotted_data(start, n);
453
454 return {data, data + n};
455}
456
461template <typename CharT, typename Traits>
462typename basic_inline_string_base<CharT, Traits>::pointer
463basic_inline_string_base<CharT, Traits>::snapshotted_data(size_t p, size_t n)
464{
465 assert(p + n <= size());
466
467 detail::conditional_add_to_tx(reinterpret_cast<CharT *>(this + 1) + p,
468 n, POBJ_XADD_ASSUME_INITIALIZED);
469
470 return reinterpret_cast<CharT *>(this + 1) + p;
471}
472
479template <typename CharT, typename Traits>
480basic_inline_string_base<CharT, Traits> &
481basic_inline_string_base<CharT, Traits>::assign(
482 basic_string_view<CharT, Traits> rhs)
483{
484 auto cpop = pmemobj_pool_by_ptr(this);
485 if (nullptr == cpop)
486 throw pmem::pool_error("Invalid pool handle.");
487
488 auto pop = pool_base(cpop);
489
490 if (rhs.size() > capacity())
491 throw std::out_of_range("inline_string capacity exceeded.");
492
493 auto initialized_mem =
494 (std::min)(rhs.size(), size()) + 1 /* sizeof('\0') */;
495
497 detail::conditional_add_to_tx(data(), initialized_mem);
498
499 if (rhs.size() > size())
500 detail::conditional_add_to_tx(
501 data() + initialized_mem,
502 rhs.size() - initialized_mem + 1,
503 POBJ_XADD_NO_SNAPSHOT);
504
505 std::copy(rhs.data(),
506 rhs.data() + static_cast<ptrdiff_t>(rhs.size()),
507 data());
508 size_ = rhs.size();
509
510 data()[static_cast<ptrdiff_t>(size_)] = '\0';
511 });
512
513 return *this;
514}
515
522template <typename T>
524 template <typename... Args>
525 static size_t
526 value(const Args &... args)
527 {
528 return sizeof(T);
529 }
530};
531
539template <typename CharT, typename Traits>
540struct total_sizeof<basic_inline_string<CharT, Traits>> {
541 static size_t
543 {
544 return sizeof(basic_inline_string_base<CharT, Traits>) +
545 (s.size() + 1 /* '\0' */) * sizeof(CharT);
546 }
547};
548
556template <typename CharT, typename Traits>
558 static size_t
560 {
562 (s.size() + 1 /* '\0' */) * sizeof(CharT);
563 }
564};
565} /* namespace experimental */
566} /* namespace obj */
567
568namespace detail
569{
570/* Check if type is pmem::obj::basic_inline_string or
571 * pmem::obj::basic_dram_inline_string */
572template <typename>
573struct is_inline_string : std::false_type {
574};
575
576template <typename CharT, typename Traits>
577struct is_inline_string<obj::experimental::basic_inline_string<CharT, Traits>>
578 : std::true_type {
579};
580
581template <typename CharT, typename Traits>
582struct is_inline_string<
583 obj::experimental::basic_dram_inline_string<CharT, Traits>>
584 : std::true_type {
585};
586
587} /* namespace detail */
588
589} /* namespace pmem */
590
591#endif /* LIBPMEMOBJ_CPP_INLINE_STRING_HPP */
constexpr size_type size() const noexcept
Returns count of characters stored in this pmem::obj::string_view data.
Definition: string_view.hpp:334
This class serves similar purpose to pmem::obj::string, but keeps the data within the same allocation...
Definition: inline_string.hpp:102
This class serves similar purpose to pmem::obj::string, but keeps the data within the same allocation...
Definition: inline_string.hpp:154
basic_inline_string(basic_string_view< CharT, Traits > v)
Definition: inline_string.hpp:169
basic_inline_string(const basic_inline_string &rhs)
Definition: inline_string.hpp:185
basic_inline_string(size_type capacity)
Definition: inline_string.hpp:177
Volatile residing on pmem class.
Definition: v.hpp:42
static void run(obj::pool_base &pool, std::function< void()> tx, Locks &... locks)
Execute a closure-like transaction and lock locks.
Definition: transaction.hpp:823
Custom pool error class.
Definition: pexceptions.hpp:45
Persistent_ptr transactional allocation functions for objects.
Persistent memory namespace.
Definition: allocation_flag.hpp:15
Persistent smart pointer.
Interface to access sequence of objects.
Our partial std::string_view implementation.
A helper trait which calculates required memory capacity (in bytes) for a type.
Definition: inline_string.hpp:523
C++ pmemobj transactions.