Ice 3.8
C++ API Reference
Loading...
Searching...
No Matches
Buffer.h
1// Copyright (c) ZeroC, Inc.
2
3#ifndef ICE_BUFFER_H
4#define ICE_BUFFER_H
5
6#include "Config.h"
7
8#include <cassert>
9#include <cstddef>
10#include <utility>
11#include <vector>
12
13namespace IceInternal
14{
15 class Buffer
16 {
17 public:
18 Buffer() : i(b.begin()) {}
19 Buffer(const std::byte* beg, const std::byte* end) : b(beg, end), i(b.begin()) {}
20 Buffer(const std::vector<std::byte>& v) : b(v), i(b.begin()) {}
21 Buffer(Buffer& o, bool adopt) : b(o.b, adopt), i(b.begin()) {}
22
23 Buffer(Buffer&& other) noexcept : b(std::move(other.b)), i(other.i) { other.i = other.b.begin(); }
24
25 Buffer& operator=(Buffer&& other) noexcept
26 {
27 if (this != &other)
28 {
29 b = std::move(other.b);
30 i = other.i;
31 other.i = other.b.begin();
32 }
33 return *this;
34 }
35
36 Buffer(const Buffer&) = delete;
37 Buffer& operator=(const Buffer&) = delete;
38
39 void swapBuffer(Buffer& other) noexcept
40 {
41 b.swap(other.b);
42 std::swap(i, other.i);
43 }
44
45 class ICE_API Container
46 {
47 public:
48 //
49 // Standard vector-like operations.
50 //
51 using value_type = std::byte;
52 using iterator = std::byte*;
53 using const_iterator = const std::byte*;
54 using reference = std::byte&;
55 using const_reference = const std::byte&;
56 using pointer = std::byte*;
57 using size_type = size_t;
58
59 Container() noexcept;
60 Container(const_iterator, const_iterator) noexcept;
61 Container(const std::vector<value_type>&) noexcept;
62 Container(Container&, bool) noexcept;
63
64 Container(Container&&) noexcept;
65 Container& operator=(Container&&) noexcept;
66
67 Container(const Container&) = delete;
68 Container& operator=(const Container&) = delete;
69
70 ~Container();
71
72 iterator begin() { return _buf; }
73
74 [[nodiscard]] const_iterator begin() const { return _buf; }
75
76 iterator end() { return _buf + _size; }
77
78 [[nodiscard]] const_iterator end() const { return _buf + _size; }
79
80 [[nodiscard]] size_type size() const { return _size; }
81
82 [[nodiscard]] bool empty() const { return !_size; }
83
84 [[nodiscard]] bool ownsMemory() const noexcept { return _owned; }
85
86 void swap(Container&) noexcept;
87
88 void clear();
89
90 void resize(size_type n) // Inlined for performance reasons.
91 {
92 if (n == 0)
93 {
94 clear();
95 }
96 else if (n > _capacity)
97 {
98 reserve(n);
99 }
100 _size = n;
101 }
102
103 void reset()
104 {
105 if (_size > 0 && _size * 2 < _capacity)
106 {
107 //
108 // If the current buffer size is smaller than the
109 // buffer capacity, we shrink the buffer memory to the
110 // current size. This is to avoid holding onto too much
111 // memory if it's not needed anymore.
112 //
113 if (++_shrinkCounter > 2)
114 {
115 reserve(_size);
116 _shrinkCounter = 0;
117 }
118 }
119 else
120 {
121 _shrinkCounter = 0;
122 }
123 _size = 0;
124 }
125
126 void push_back(value_type v)
127 {
128 resize(_size + 1);
129 _buf[_size - 1] = v;
130 }
131
132 reference operator[](size_type n)
133 {
134 assert(n < _size);
135 return _buf[n];
136 }
137
138 const_reference operator[](size_type n) const
139 {
140 assert(n < _size);
141 return _buf[n];
142 }
143
144 private:
145 void reserve(size_type);
146
147 pointer _buf;
148 size_type _size;
149 size_type _capacity;
150 int _shrinkCounter;
151 bool _owned;
152 };
153
154 Container b;
155 Container::iterator i;
156 };
157}
158
159#endif