ProteoWizard
BinaryData.hpp
Go to the documentation of this file.
1//
2// $Id$
3//
4//
5// Original author: Matt Chambers <matt.chambers42 .@. gmail.com>
6//
7// Copyright 2017 Matt Chambers
8//
9// Licensed under the Apache License, Version 2.0 (the "License");
10// you may not use this file except in compliance with the License.
11// You may obtain a copy of the License at
12//
13// http://www.apache.org/licenses/LICENSE-2.0
14//
15// Unless required by applicable law or agreed to in writing, software
16// distributed under the License is distributed on an "AS IS" BASIS,
17// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18// See the License for the specific language governing permissions and
19// limitations under the License.
20//
21
22#ifndef __BINARYDATA_HPP__
23#define __BINARYDATA_HPP__
24
25#ifdef __cplusplus_cli
26#pragma managed(push, off)
27#endif
28
29#include <algorithm>
30#include <vector>
31#include <stdexcept>
32#include <memory>
33#include <iterator>
34#include <limits>
35#include <boost/assert.hpp>
37
38
39namespace pwiz {
40namespace util {
41
42/// A custom vector class that can store its contents in either a std::vector or a cli::array (when compiled with .NET).
43template <typename T>
45{
46 public:
47
48 typedef std::size_t size_type;
49 typedef std::ptrdiff_t difference_type;
50 typedef T value_type;
51 typedef T &reference;
52 typedef const T &const_reference;
53
54 class PWIZ_API_DECL const_iterator : public std::iterator<std::random_access_iterator_tag, const T>
55 {
56 public:
57
58 const T& operator*() const { return *current_; }
59 const T* operator->() const { return current_; }
60 const_iterator& operator++() { ++current_; return *this; }
61 const_iterator operator++(int) { const_iterator copy = *this; ++(*this); return copy; }
62 const_iterator& operator--() { --current_; return *this; }
63 const_iterator operator--(int) { const_iterator copy = *this; --(*this); return copy; }
64 const_iterator& operator+=(difference_type n) { current_ += n; return *this; }
65 const_iterator& operator-=(difference_type n) { current_ -= n; return *this; }
66 const_iterator operator+(difference_type n) const { const_iterator copy = *this; copy += n; return copy; }
67 const_iterator operator-(difference_type n) const { const_iterator copy = *this; copy -= n; return copy; }
68 difference_type operator-(const const_iterator& rhs) const { return current_ - rhs.current_; }
69 const T& operator[](difference_type n) const { return *(current_ + n); }
70
71 bool operator!=(const const_iterator& that) const { return current_ != that.current_; }
72 bool operator==(const const_iterator& that) const { return current_ == that.current_; }
73 bool operator<(const const_iterator& that) const { return current_ < that.current_; }
74 bool operator<=(const const_iterator& that) const { return current_ <= that.current_; }
75 bool operator>(const const_iterator& that) const { return current_ > that.current_; }
76 bool operator>=(const const_iterator& that) const { return current_ >= that.current_; }
77
78 const_iterator() : current_(NULL) {}
79 const_iterator(const const_iterator& rhs) : current_(rhs.current_) {}
80
81 protected:
82 const_iterator(const BinaryData& binaryData, bool begin = true);
83
84 friend class BinaryData;
85 const T* current_;
86 };
87
88 class PWIZ_API_DECL iterator : public std::iterator<std::random_access_iterator_tag, T>
89 {
90 public:
91
92 T& operator*() const { return *current_; }
93 T* operator->() const { return current_; }
94 iterator& operator++() { ++current_; return *this; }
95 iterator operator++(int) { iterator copy = *this; ++(*this); return copy; }
96 iterator& operator--() { --current_; return *this; }
97 iterator operator--(int) { iterator copy = *this; --(*this); return copy; }
98 iterator& operator+=(difference_type n) { current_ += n; return *this; }
99 iterator& operator-=(difference_type n) { current_ -= n; return *this; }
100 iterator operator+(difference_type n) const { iterator copy = *this; copy += n; return copy; }
101 iterator operator-(difference_type n) const { iterator copy = *this; copy -= n; return copy; }
102 difference_type operator-(const iterator& rhs) const { return current_ - rhs.current_; }
103 T& operator[](difference_type n) const { return *(current_ + n); }
104
105 bool operator!=(const iterator& that) const { return current_ != that.current_; }
106 bool operator==(const iterator& that) const { return current_ == that.current_; }
107 bool operator<(const iterator& that) const { return current_ < that.current_; }
108 bool operator<=(const iterator& that) const { return current_ <= that.current_; }
109 bool operator>(const iterator& that) const { return current_ > that.current_; }
110 bool operator>=(const iterator& that) const { return current_ >= that.current_; }
111
112 iterator() : current_(NULL) {}
113 iterator(const iterator& rhs) : current_(rhs.current_) {}
114
115 protected:
116 iterator(BinaryData& binaryData, bool begin = true);
117
118 friend class BinaryData;
120 };
121 typedef std::reverse_iterator<iterator> reverse_iterator;
122 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
123
124#pragma region Ctors/Dtor
125 BinaryData(size_type elements = 0, T t = T());
126
127 BinaryData(const BinaryData &source);
128
130
131 BinaryData(void* cliNumericArray);
132
133 BinaryData &operator=(void* cliNumericArray);
134
136#pragma endregion
137
138#pragma region Iterators/accessors
139
140 bool empty() const /*throw()*/
141 {
142 return size() == 0;
143 }
144
145 size_t size() const /*throw()*/
146 {
147 return _size();
148 }
149
150 size_t capacity() const /*throw()*/
151 {
152 return _capacity();
153 }
154
156 {
157 if (n > _capacity())
158 _reserve(n);
159 }
160
161 size_type max_size() const /*throw()*/
162 {
163 return std::numeric_limits<int>().max() / sizeof(T);
164 }
165
166 const_iterator cbegin() const /*throw(std::runtime_error)*/
167 {
168 return const_iterator(*this);
169 }
170
171 iterator begin() /*throw(std::runtime_error)*/
172 {
173 return iterator(*this);
174 }
175
176 const_iterator begin() const /*throw(std::runtime_error)*/
177 {
178 return cbegin();
179 }
180
181 const_iterator cend() const /*throw(std::runtime_error)*/
182 {
183 return const_iterator(*this, false);
184 }
185
186 const_iterator end() const /*throw(std::runtime_error)*/
187 {
188 return cend();
189 }
190
191 iterator end() /*throw(std::runtime_error)*/
192 {
193 return iterator(*this, false);
194 }
195
196 reverse_iterator rbegin() /*throw(std::runtime_error)*/
197 {
198 return reverse_iterator(end());
199 }
200
201 const_reverse_iterator crbegin() const /*throw(std::runtime_error)*/
202 {
203 return const_reverse_iterator(cend());
204 }
205
206 const_reverse_iterator rbegin() const /*throw(std::runtime_error)*/
207 {
208 return crbegin();
209 }
210
211 reverse_iterator rend() /*throw(std::runtime_error)*/
212 {
213 return reverse_iterator(begin());
214 }
215
216 const_reverse_iterator crend() const /*throw(std::runtime_error)*/
217 {
218 return const_reverse_iterator(begin());
219 }
220
221 const_reverse_iterator rend() const /*throw(std::runtime_error)*/
222 {
223 return crend();
224 }
225
226 const_reference front() const /*throw(std::runtime_error)*/
227 {
228 BOOST_ASSERT(!empty());
229 return *begin();
230 }
231
232 reference front() /*throw(std::runtime_error)*/
233 {
234 BOOST_ASSERT(!empty());
235 return *begin();
236 }
237
238 const_reference back() const /*throw(std::runtime_error)*/
239 {
240 BOOST_ASSERT(!empty());
241 return *(--cend());
242 }
243
244 reference back() /*throw(std::runtime_error)*/
245 {
246 BOOST_ASSERT(!empty());
247 return *(--end());
248 }
249
250 const_reference operator[] (size_type index) const; /*throw(std::runtime_error)*/
251
253
254 const_reference at(size_type index) const /*throw(std::runtime_error)*/
255 {
256 if (index < 0 || index >= size())
257 throw std::out_of_range("out of range");
258 return (*this)[index];
259 }
260
261 reference at(size_type index) /*throw(std::runtime_error)*/
262 {
263 if (index < 0 || index >= size())
264 throw std::out_of_range("out of range");
265 return (*this)[index];
266 }
267#pragma endregion
268
269#pragma region Mutators
271 {
272 _assign(that);
273 return *this;
274 }
275
276 BinaryData &operator=(const std::vector<T>& source)
277 {
278 _assign(source);
279 return *this;
280 }
281
282 void swap(BinaryData &that) /*throw()*/
283 {
284 _swap(that);
285 }
286
287 void swap(std::vector<T> &that) /*throw()*/
288 {
289 _swap(that);
290 }
291
292 template <typename Iter>
293 void assign(const Iter& first, const Iter& last)
294 {
295 clear();
296 insert(end(), first, last);
297 }
298
299 // Insert an element BEFORE i within the vector.
300 // Call insert(end(), x) or push_back(x) to append.
301 iterator insert(iterator i, const T& x = T()) /*throw(std::runtime_error)*/
302 {
303 BOOST_ASSERT(i >= begin() && i <= end());
304 size_t Offset = i - begin();
305 insert(i, 1, x);
306 return begin() + Offset;
307 }
308
309 // Insert a repetition of x BEFORE i within the vector.
310 void insert(iterator i, size_type n, const T &x) /*throw(std::runtime_error)*/
311 {
312 BOOST_ASSERT(i >= begin() && i <= end());
313 size_t OldSize = size();
314 size_type offset = i - begin();
315 resize(OldSize + n);
316 std::copy_backward(begin() + offset, begin() + OldSize, end());
317 std::fill(begin() + offset, begin() + offset + n, x);
318 }
319
320 // Insert a sequence of elements BEFORE i within the vector.
321 template<typename Iter>
322 void insert(iterator i, const Iter& first, const Iter& last) /*throw(std::runtime_error)*/
323 {
324 BOOST_ASSERT(last >= first);
325 BOOST_ASSERT(i >= begin() && i <= end());
326 size_t count = last - first;
327 if (count == 0)
328 return;
329 size_t offset = i - begin(), old_size = size();
330 resize(old_size + count);
331 for (iterator j = begin() + old_size, k = end(); j != begin() + offset; )
332 std::iter_swap(--j, --k);
333 std::copy(first, last, begin() + offset);
334 }
335
337 {
338 difference_type Offset = i - begin();
339 std::copy(i + 1, end(), i);
340 pop_back();
341 return begin() + Offset;
342 }
343
345 {
346 difference_type Offset = From - begin();
347 iterator i = std::copy(To, end(), From);
348 resize(i - begin());
349 return begin() + Offset;
350 }
351
352 void resize(size_type elements, const T &FillWith)
353 {
354 _resize(elements, FillWith);
355 }
356
357 void resize(size_type elements)
358 {
359 _resize(elements);
360 }
361
362 void push_back(const T &value) /*throw(std::runtime_error)*/
363 {
364 _resize(size() + 1);
365 back() = value;
366 }
367
368 void pop_back() /*throw(std::runtime_error)*/
369 {
370 _resize(size() - 1);
371 }
372
373 void clear()
374 {
375 _resize(0);
376 }
377#pragma endregion
378
379 void* managedStorage() const;
380
381 //operator std::vector<T>&(); // not compatible with caching iterators
382 operator const std::vector<T>&() const;
383 //operator std::vector<T>() const;
384
385 private:
386 class Impl;
387
388#ifdef WIN32
389#pragma warning(push)
390#pragma warning(disable: 4251)
391 std::unique_ptr<Impl> _impl;
392#pragma warning(pop)
393#else
394 std::unique_ptr<Impl> _impl;
395#endif
396
397 void _alloc(size_type elements, const T & t);
398 void _reserve(size_type elements);
399 void _resize(size_type elements);
400 void _resize(size_type elements, const T & FillWith);
401 void _swap(BinaryData & that);
402 void _swap(std::vector<T>& that);
403 void _assign(const BinaryData & that);
404 void _assign(const std::vector<T>& that);
407};
408
409} // util
410} // pwiz
411
412
413namespace std {
414template <typename T> void swap(pwiz::util::BinaryData<T>& lhs, std::vector<T>& rhs) { lhs.swap(rhs); }
415template <typename T> void swap(std::vector<T>& lhs, pwiz::util::BinaryData<T>& rhs) { rhs.swap(lhs); }
416}
417
418#ifdef __cplusplus_cli
419#pragma managed(pop)
420#endif
421
422#endif //__BINARYDATA_HPP__
#define PWIZ_API_DECL
Definition Export.hpp:32
KernelTraitsBase< Kernel >::space_type::abscissa_type x
Kernel k
const_iterator operator+(difference_type n) const
const_iterator & operator+=(difference_type n)
bool operator<=(const const_iterator &that) const
bool operator>=(const const_iterator &that) const
bool operator!=(const const_iterator &that) const
const_iterator & operator-=(difference_type n)
difference_type operator-(const const_iterator &rhs) const
bool operator<(const const_iterator &that) const
bool operator==(const const_iterator &that) const
bool operator>(const const_iterator &that) const
const T & operator[](difference_type n) const
const_iterator operator-(difference_type n) const
const_iterator(const const_iterator &rhs)
const_iterator(const BinaryData &binaryData, bool begin=true)
iterator(const iterator &rhs)
iterator & operator+=(difference_type n)
iterator(BinaryData &binaryData, bool begin=true)
bool operator!=(const iterator &that) const
iterator operator+(difference_type n) const
iterator & operator-=(difference_type n)
T & operator[](difference_type n) const
difference_type operator-(const iterator &rhs) const
bool operator<=(const iterator &that) const
bool operator>=(const iterator &that) const
bool operator<(const iterator &that) const
bool operator>(const iterator &that) const
bool operator==(const iterator &that) const
iterator operator-(difference_type n) const
A custom vector class that can store its contents in either a std::vector or a cli::array (when compi...
reference at(size_type index)
const_iterator cend() const
BinaryData & operator=(const BinaryData &that)
BinaryData(const BinaryData &source)
iterator erase(iterator From, iterator To)
iterator erase(iterator i)
const_reverse_iterator rend() const
void swap(std::vector< T > &that)
void reserve(size_type n)
reference operator[](size_type index)
std::ptrdiff_t difference_type
void assign(const Iter &first, const Iter &last)
void _reserve(size_type elements)
void _resize(size_type elements, const T &FillWith)
std::reverse_iterator< iterator > reverse_iterator
std::unique_ptr< Impl > _impl
void resize(size_type elements, const T &FillWith)
void resize(size_type elements)
std::reverse_iterator< const_iterator > const_reverse_iterator
void insert(iterator i, size_type n, const T &x)
size_t capacity() const
void * managedStorage() const
const_reverse_iterator crbegin() const
void _alloc(size_type elements, const T &t)
void insert(iterator i, const Iter &first, const Iter &last)
void _assign(const BinaryData &that)
void _swap(BinaryData &that)
const_iterator begin() const
BinaryData & operator=(void *cliNumericArray)
void _swap(std::vector< T > &that)
BinaryData(size_type elements=0, T t=T())
size_type _capacity() const
BinaryData(const_iterator first, const_iterator last)
reverse_iterator rbegin()
size_type max_size() const
const_reverse_iterator crend() const
BinaryData & operator=(const std::vector< T > &source)
size_type _size() const
const_reference front() const
const_reference at(size_type index) const
const_reference back() const
reverse_iterator rend()
BinaryData(void *cliNumericArray)
void _assign(const std::vector< T > &that)
const_iterator end() const
void swap(BinaryData &that)
const_iterator cbegin() const
const_reverse_iterator rbegin() const
void _resize(size_type elements)
void push_back(const T &value)
iterator insert(iterator i, const T &x=T())
STL namespace.
void swap(pwiz::util::BinaryData< T > &lhs, std::vector< T > &rhs)