1 | /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
2 | #ident "$Id$" |
3 | /*====== |
4 | This file is part of PerconaFT. |
5 | |
6 | |
7 | Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. |
8 | |
9 | PerconaFT is free software: you can redistribute it and/or modify |
10 | it under the terms of the GNU General Public License, version 2, |
11 | as published by the Free Software Foundation. |
12 | |
13 | PerconaFT is distributed in the hope that it will be useful, |
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | GNU General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU General Public License |
19 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
20 | |
21 | ---------------------------------------- |
22 | |
23 | PerconaFT is free software: you can redistribute it and/or modify |
24 | it under the terms of the GNU Affero General Public License, version 3, |
25 | as published by the Free Software Foundation. |
26 | |
27 | PerconaFT is distributed in the hope that it will be useful, |
28 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
29 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
30 | GNU Affero General Public License for more details. |
31 | |
32 | You should have received a copy of the GNU Affero General Public License |
33 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
34 | ======= */ |
35 | |
36 | #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." |
37 | |
38 | #pragma once |
39 | |
40 | #include <cassert> |
41 | #include <iterator> |
42 | #include <memory> |
43 | |
44 | #include <db.h> |
45 | |
46 | namespace ftcxx { |
47 | |
48 | class Slice { |
49 | public: |
50 | Slice() |
51 | : _data(nullptr), |
52 | _size(0) |
53 | {} |
54 | |
55 | explicit Slice(size_t sz) |
56 | : _buf(new char[sz], std::default_delete<char[]>()), |
57 | _data(_buf.get()), |
58 | _size(sz) |
59 | {} |
60 | |
61 | Slice(const char *p, size_t sz) |
62 | : _data(p), |
63 | _size(sz) |
64 | {} |
65 | |
66 | explicit Slice(const DBT &d) |
67 | : _data(reinterpret_cast<char *>(d.data)), |
68 | _size(d.size) |
69 | {} |
70 | |
71 | explicit Slice(const std::string &str) |
72 | : _data(str.c_str()), |
73 | _size(str.size()) |
74 | {} |
75 | |
76 | Slice(const Slice &other) |
77 | : _buf(other._buf), |
78 | _data(other._data), |
79 | _size(other._size) |
80 | {} |
81 | |
82 | Slice& operator=(const Slice &other) { |
83 | _buf = other._buf; |
84 | _data = other._data; |
85 | _size = other._size; |
86 | return *this; |
87 | } |
88 | |
89 | Slice(Slice&& other) |
90 | : _buf(), |
91 | _data(nullptr), |
92 | _size(0) |
93 | { |
94 | std::swap(_buf, other._buf); |
95 | std::swap(_data, other._data); |
96 | std::swap(_size, other._size); |
97 | } |
98 | |
99 | Slice& operator=(Slice&& other) { |
100 | std::swap(_buf, other._buf); |
101 | std::swap(_data, other._data); |
102 | std::swap(_size, other._size); |
103 | return *this; |
104 | } |
105 | |
106 | template<typename T> |
107 | static Slice slice_of(const T &v) { |
108 | return Slice(reinterpret_cast<const char *>(&v), sizeof v); |
109 | } |
110 | |
111 | template<typename T> |
112 | T as() const { |
113 | assert(size() == sizeof(T)); |
114 | const T *p = reinterpret_cast<const T *>(data()); |
115 | return *p; |
116 | } |
117 | |
118 | const char *data() const { return _data; } |
119 | |
120 | char *mutable_data() const { |
121 | assert(_buf); |
122 | return _buf.get(); |
123 | } |
124 | |
125 | size_t size() const { return _size; } |
126 | |
127 | bool empty() const { return size() == 0; } |
128 | |
129 | char operator[](size_t n) const { |
130 | assert(n < size()); |
131 | return _data[n]; |
132 | } |
133 | |
134 | char *begin() { return mutable_data(); } |
135 | char *end() { return mutable_data() + size(); } |
136 | char *rbegin() { return end(); } |
137 | char *rend() { return begin(); } |
138 | const char *begin() const { return data(); } |
139 | const char *end() const { return data() + size(); } |
140 | const char *rbegin() const { return end(); } |
141 | const char *rend() const { return begin(); } |
142 | const char *cbegin() const { return data(); } |
143 | const char *cend() const { return data() + size(); } |
144 | const char *crbegin() const { return end(); } |
145 | const char *crend() const { return begin(); } |
146 | |
147 | Slice copy() const { |
148 | Slice s(size()); |
149 | std::copy(begin(), end(), s.begin()); |
150 | return s; |
151 | } |
152 | |
153 | Slice owned() const { |
154 | if (_buf) { |
155 | return *this; |
156 | } else { |
157 | return copy(); |
158 | } |
159 | } |
160 | |
161 | DBT dbt() const { |
162 | DBT d; |
163 | d.data = const_cast<void *>(static_cast<const void *>(data())); |
164 | d.size = size(); |
165 | d.ulen = size(); |
166 | d.flags = 0; |
167 | return d; |
168 | } |
169 | |
170 | private: |
171 | std::shared_ptr<char> _buf; |
172 | const char *_data; |
173 | size_t _size; |
174 | }; |
175 | |
176 | } // namespace ftcxx |
177 | |
178 | namespace std { |
179 | |
180 | template<> |
181 | class iterator_traits<ftcxx::Slice> { |
182 | typedef typename std::iterator_traits<const char *>::difference_type difference_type; |
183 | typedef typename std::iterator_traits<const char *>::value_type value_type; |
184 | typedef typename std::iterator_traits<const char *>::pointer pointer; |
185 | typedef typename std::iterator_traits<const char *>::reference reference; |
186 | typedef typename std::iterator_traits<const char *>::iterator_category iterator_category; |
187 | }; |
188 | |
189 | } // namespace std |
190 | |