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 
39 namespace pwiz {
40 namespace 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).
43 template <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 
129  BinaryData(const_iterator first, const_iterator last);
130 
131  BinaryData(void* cliNumericArray);
132 
133  BinaryData &operator=(void* cliNumericArray);
134 
135  ~BinaryData();
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 
155  void reserve(size_type n)
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 
252  reference operator[](size_type index);
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 
336  iterator erase(iterator i)
337  {
338  difference_type Offset = i - begin();
339  std::copy(i + 1, end(), i);
340  pop_back();
341  return begin() + Offset;
342  }
343 
344  iterator erase(iterator From, iterator To)
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);
405  size_type _size() const;
406  size_type _capacity() const;
407 };
408 
409 } // util
410 } // pwiz
411 
412 
413 namespace std {
414 template <typename T> void swap(pwiz::util::BinaryData<T>& lhs, std::vector<T>& rhs) { lhs.swap(rhs); }
415 template <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__
std::unique_ptr< Impl > _impl
Definition: BinaryData.hpp:386
iterator erase(iterator i)
Definition: BinaryData.hpp:336
void reserve(size_type n)
Definition: BinaryData.hpp:155
void push_back(const T &value)
Definition: BinaryData.hpp:362
difference_type operator-(const iterator &rhs) const
Definition: BinaryData.hpp:102
PWIZ_API_DECL Element * elements()
bool operator>(const const_iterator &that) const
Definition: BinaryData.hpp:75
iterator & operator+=(difference_type n)
Definition: BinaryData.hpp:98
bool operator<(const iterator &that) const
Definition: BinaryData.hpp:107
std::ptrdiff_t difference_type
Definition: BinaryData.hpp:49
size_t capacity() const
Definition: BinaryData.hpp:150
reverse_iterator rbegin()
Definition: BinaryData.hpp:196
void insert(iterator i, size_type n, const T &x)
Definition: BinaryData.hpp:310
difference_type operator-(const const_iterator &rhs) const
Definition: BinaryData.hpp:68
STL namespace.
bool operator>=(const iterator &that) const
Definition: BinaryData.hpp:110
const_reverse_iterator crbegin() const
Definition: BinaryData.hpp:201
bool operator!=(const iterator &that) const
Definition: BinaryData.hpp:105
void resize(size_type elements, const T &FillWith)
Definition: BinaryData.hpp:352
T & operator[](difference_type n) const
Definition: BinaryData.hpp:103
const_iterator cbegin() const
Definition: BinaryData.hpp:166
bool operator==(const const_iterator &that) const
Definition: BinaryData.hpp:72
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition: BinaryData.hpp:122
BinaryData & operator=(const std::vector< T > &source)
Definition: BinaryData.hpp:276
void swap(pwiz::util::BinaryData< T > &lhs, std::vector< T > &rhs)
Definition: BinaryData.hpp:414
bool operator>(const iterator &that) const
Definition: BinaryData.hpp:109
const_iterator(const const_iterator &rhs)
Definition: BinaryData.hpp:79
const_iterator operator-(difference_type n) const
Definition: BinaryData.hpp:67
const_reverse_iterator rend() const
Definition: BinaryData.hpp:221
bool operator==(const iterator &that) const
Definition: BinaryData.hpp:106
A custom vector class that can store its contents in either a std::vector or a cli::array (when compi...
Definition: BinaryData.hpp:44
void resize(size_type elements)
Definition: BinaryData.hpp:357
iterator(const iterator &rhs)
Definition: BinaryData.hpp:113
bool operator<=(const const_iterator &that) const
Definition: BinaryData.hpp:74
const_reverse_iterator crend() const
Definition: BinaryData.hpp:216
bool operator>=(const const_iterator &that) const
Definition: BinaryData.hpp:76
size_type max_size() const
Definition: BinaryData.hpp:161
const_iterator cend() const
Definition: BinaryData.hpp:181
iterator insert(iterator i, const T &x=T())
Definition: BinaryData.hpp:301
void swap(std::vector< T > &that)
Definition: BinaryData.hpp:287
bool operator<=(const iterator &that) const
Definition: BinaryData.hpp:108
void swap(BinaryData &that)
Definition: BinaryData.hpp:282
const_iterator operator+(difference_type n) const
Definition: BinaryData.hpp:66
const T & operator[](difference_type n) const
Definition: BinaryData.hpp:69
iterator operator-(difference_type n) const
Definition: BinaryData.hpp:101
#define PWIZ_API_DECL
Definition: Export.hpp:32
const_iterator end() const
Definition: BinaryData.hpp:186
void assign(const Iter &first, const Iter &last)
Definition: BinaryData.hpp:293
iterator erase(iterator From, iterator To)
Definition: BinaryData.hpp:344
iterator operator+(difference_type n) const
Definition: BinaryData.hpp:100
size_t size() const
Definition: BinaryData.hpp:145
Kernel k
reference at(size_type index)
Definition: BinaryData.hpp:261
std::reverse_iterator< iterator > reverse_iterator
Definition: BinaryData.hpp:121
const_reference front() const
Definition: BinaryData.hpp:226
const_iterator & operator+=(difference_type n)
Definition: BinaryData.hpp:64
KernelTraitsBase< Kernel >::space_type::abscissa_type x
bool operator!=(const const_iterator &that) const
Definition: BinaryData.hpp:71
PWIZ_API_DECL std::string value(const std::string &id, const std::string &name)
convenience function to extract a named value from an id string
bool operator<(const const_iterator &that) const
Definition: BinaryData.hpp:73
iterator & operator-=(difference_type n)
Definition: BinaryData.hpp:99
reverse_iterator rend()
Definition: BinaryData.hpp:211
const_reference at(size_type index) const
Definition: BinaryData.hpp:254
const_reference back() const
Definition: BinaryData.hpp:238
const_iterator & operator-=(difference_type n)
Definition: BinaryData.hpp:65
void insert(iterator i, const Iter &first, const Iter &last)
Definition: BinaryData.hpp:322
const_iterator begin() const
Definition: BinaryData.hpp:176
const_reverse_iterator rbegin() const
Definition: BinaryData.hpp:206
BinaryData & operator=(const BinaryData &that)
Definition: BinaryData.hpp:270