mn_vector.hpp
Go to the documentation of this file.
1 
20 #ifndef _MINILIB_4dcc23da_d2cf_41da_9e29_571d9f17efbe_H_
21 #define _MINILIB_4dcc23da_d2cf_41da_9e29_571d9f17efbe_H_
22 
23 #include "../mn_config.hpp"
24 
25 #include <assert.h>
26 
27 #include "../mn_typetraits.hpp"
28 #include "../mn_algorithm.hpp"
29 #include "../mn_allocator.hpp"
30 
31 namespace mn {
32  namespace container {
33 
34 
35  template<typename T, class TAllocator = memory::default_allocator>
37  using allocator_type = TAllocator;
39  using value_type = T;
40  using pointer = value_type*;
42  using lreference = T&&;
44 
45 
46 
47  explicit basic_vector_storage(const allocator_type& allocator)
48  : m_begin(0), m_end(0), m_capacityEnd(0), m_allocator(allocator) { }
49 
50  void reallocate(size_type newCapacity, size_type oldSize) {
51 
52  void* mem = m_allocator.allocate(newCapacity, sizeof(value_type) );
53  pointer newBegin = new (mem) value_type();
54 
55  const size_type newSize = oldSize < newCapacity ? oldSize : newCapacity;
56  // Copy old data if needed.
57  if (m_begin) {
58  mn::copy_construct_n(m_begin, newSize, newBegin);
59  destroy(m_begin, oldSize);
60  }
61  m_begin = newBegin;
62  m_end = m_begin + newSize;
63  m_capacityEnd = m_begin + newCapacity;
64  assert(invariant());
65  }
66  void reallocate_discard_old(size_type newCapacity) {
67  assert(newCapacity > size_type(m_capacityEnd - m_begin));
68 
69  void* mem = m_allocator.allocate(newCapacity, sizeof(value_type) );
70  pointer newBegin = new (mem) value_type();
71 
72 
73  const size_type currSize((size_type)(m_end - m_begin));
74 
75  if (m_begin) destroy(m_begin, currSize);
76 
77  m_begin = newBegin;
78  m_end = m_begin + currSize;
79  m_capacityEnd = m_begin + newCapacity;
80  assert(invariant());
81  }
82 
83  void destroy(pointer ptr, size_type n) {
84  mn::destruct_n(ptr, n);
85 
86 
88  ptr->~value_type();
89 
90  m_allocator.deallocate(ptr, n, mn::alignment_for(sizeof(n)));
91 
92  }
93  void reset() {
94  if (m_begin) m_allocator.free(m_begin);
95  m_begin = m_end = 0;
96  m_capacityEnd = 0;
97  }
98 
99  bool invariant() const {
100  return m_end >= m_begin;
101  }
102 
103  void swap( self_type& other ) {
104  mn::swap(m_begin, other.m_begin);
105  mn::swap(m_end, other.m_end);
108  }
109 
114  };
115 
116  template<typename T, class TAllocator, class TStorage = basic_vector_storage<T, TAllocator> >
117  class basic_vector : private TStorage {
118  public:
120 
121  using value_type = T;
122  using pointer = T*;
123  using reference = T&;
124  using lreference = T&&;
125  using const_reference = const T&;
127  using iterator = pointer;
128  using const_iterator = const pointer;
129  using allocator_type = TAllocator;
131 
132  static const size_type npos = size_type(-1);
133  static const size_type kInitialCapacity = 16;
134 
135  explicit basic_vector(const allocator_type& allocator = allocator_type())
136  : TStorage(allocator) { }
137 
138  explicit basic_vector(size_type initialSize, const allocator_type& allocator = allocator_type())
139  : TStorage(allocator) { resize(initialSize); }
140 
142  : TStorage(allocator) { assign(first, last); }
143 
144  basic_vector(const basic_vector& rhs, const allocator_type& allocator = allocator_type())
145  : TStorage(allocator) {
146  if(rhs.size() == 0) return;
147 
148  this->reallocate_discard_old(rhs.capacity());
150 
151  m_end = m_begin + rhs.size();
152  assert(invariant());
153  }
154 
156  if (TStorage::m_begin != 0) TStorage::destroy(TStorage::m_begin, size());
157  }
158 
159 
160 
161  void copy(const basic_vector& rhs) {
162  const size_type newSize = rhs.size();
163 
164  if (newSize > capacity())
166 
167  mn::copy_construct_n(rhs.m_begin, newSize, m_begin);
168  m_end = m_begin + newSize;
169 
170  assert(invariant());
171  }
172 
173  iterator begin() { return m_begin; }
174  iterator end() { return m_end; }
175 
176  size_type size() const { return size_type(m_end - m_begin); }
177  bool empty() const { return m_begin == m_end; }
178 
180 
181  pointer data() { return empty() ? 0 : m_begin; }
182 
183  reference front() { assert(!empty()); return *begin(); }
184  const reference cfront() { assert(!empty()); return *begin(); }
185  reference back() { assert(!empty()); return *(end() - 1); }
186  const reference cback() { assert(!empty()); return *(end() - 1); }
187 
188  reference at(size_type i) { assert(i < size()); return m_begin[i]; }
189  const reference const_at(size_type i) { assert(i < size()); return m_begin[i]; }
190 
191  using TStorage::swap;
192 
194  if (m_end >= m_capacityEnd) grow();
196  }
197  inline void push_back (lreference v) {
198  if (m_end >= m_capacityEnd) grow();
200  }
201 
202  void push_back() {
203  if (m_end == m_capacityEnd) grow();
205  }
206  void pop_back() {
207  assert(!empty()); --m_end;
208  mn::destruct<iterator>(m_end);
209  }
210 
211  void assign(const pointer first, const pointer last) {
212  assert(!validate_iterator(first));
213  assert(!validate_iterator(last));
214 
215  const size_type count = size_type(last - first);
216  assert(count > 0);
217  clear();
218 
219  if (m_begin + count > m_capacityEnd)
221 
222  mn::copy_n(first, count, m_begin);
223  m_end = m_begin + count;
224 
225  assert(invariant());
226  }
227 
228  void insert(size_type index, size_type n, const reference val) {
229  assert(invariant());
230 
231  const size_type indexEnd = index + n;
232  const size_type prevSize = size();
233 
234  if (m_end + n > m_capacityEnd) {
235  reallocate(compute_new_capacity(prevSize + n), prevSize);
236  }
237 
238  if (indexEnd > prevSize) {
239  const size_type numCopy = prevSize - index;
240  const size_type numAppend = indexEnd - prevSize;
241 
242  assert(numCopy >= 0 && numAppend >= 0);
243  assert(numAppend + numCopy == n);
244 
245  iterator itOut = m_begin + prevSize;
246  for (size_type i = 0; i < numAppend; ++i, ++itOut) {
247  mn::copy_construct(itOut, val);
248  }
249 
250  mn::copy_construct_n(m_begin + index, numCopy, itOut);
251 
252  for (size_type i = 0; i < numCopy; ++i) {
253  m_begin[index + i] = val;
254  }
255  } else {
257  iterator insertPos = m_begin + index;
258  mn::move_n(insertPos, prevSize - indexEnd, insertPos + n);
259  for (size_type i = 0; i < n; ++i) {
260  insertPos[i] = val;
261  }
262  }
263  m_end += n;
264  }
265 
266  void insert(iterator it, size_type n, const reference val) {
267  assert(validate_iterator(it));
268  assert(invariant());
269  insert(size_type(it - m_begin), n, val);
270  }
271 
272 
273 
275  assert(validate_iterator(it));
276  assert(invariant());
277 
278  const size_type index = (size_type)(it - m_begin);
279  if (m_end == m_capacityEnd) {
280  grow();
281  it = m_begin + index;
282  } else {
284  }
285 
286  if (m_end > it) {
288  const size_type prevSize = size();
289  assert(index <= prevSize);
290  const size_type toMove = prevSize - index;
291 
293  } else {
294  assert(it < m_end);
295  const size_t n = reinterpret_cast<uintptr_t>(m_end) - reinterpret_cast<uintptr_t>(it);
296  memmove(it + 1, it, n);
297  }
298  }
299  *it = val;
300  ++m_end;
301  assert(invariant());
302 
303  return it;
304  }
305 
307  assert(validate_iterator(it));
308  assert(it != end());
309 
310  // Move everything down, overwriting *it
311  if (it + 1 < m_end) {
313  }
314  --m_end;
315  mn::destruct<iterator>(m_end);
316  return it;
317  }
319  assert(validate_iterator(first));
320  assert(validate_iterator(last));
321 
322  if (last <= first) return end();
323 
324  const size_type indexFirst = size_type(first - m_begin);
325  const size_type toRemove = size_type(last - first);
326 
327  if (toRemove > 0) {
329  shrink(size() - toRemove);
330  }
331  return m_begin + indexFirst;
332  }
333 
334  void resize(size_type n) {
335  if (n > size()) insert(m_end, n - size(), value_type());
336  else shrink(n);
337  }
338 
339  void reserve(size_type n) {
340  if (n > capacity()) reallocate(n, size());
341  }
342 
343  void clear() {
344  shrink(0);
345  assert(invariant());
346  }
347 
348  void reset() {
349  TStorage::reset();
350  assert(invariant());
351  }
352 
353  void set_capacity(size_type newCapacity) {
354  reallocate(newCapacity, size());
355  }
356 
357  size_type index_of(const reference item, size_type index = 0) const {
358  assert(index >= 0 && index < size());
359  size_type _pos = npos;
360 
361  for ( ; index < size(); ++index) {
362  if (m_begin[index] == item) {
363  _pos = index; break;
364  }
365  }
366  return _pos;
367  }
368 
369  iterator find(const reference item) {
370  iterator itEnd = end();
371 
372  for (iterator it = begin(); it != itEnd; ++it)
373  if (*it == item) { itEnd = it; break; }
374  return itEnd;
375  }
376 
377  const allocator_type& get_allocator() const {
378  return m_allocator;
379  }
380 
381  void set_allocator(const allocator_type& allocator) {
382  if(empty()) m_allocator = allocator;
383  }
384 
386  return it >= begin() && it <= end();
387  }
388 
390  copy(rhs);
391  return *this;
392  }
394  return at(i);
395  }
396 
397  const reference operator[](size_type i) const {
398  return at(i);
399  }
400  private:
401  size_type compute_new_capacity(size_type newMinCapacity) const {
402  const size_type c = capacity();
403  return (newMinCapacity > c * 2 ? newMinCapacity : (c == 0 ? kInitialCapacity : c * 2));
404  }
405 
406  inline void grow() {
407  assert(m_end == m_capacityEnd);
408  const size_type c = capacity();
409  reallocate((m_capacityEnd == 0 ? kInitialCapacity : c * 2), c);
410  }
411 
412  inline void shrink(size_type newSize) {
413  assert(newSize <= size());
414  const size_type toShrink = size() - newSize;
415  mn::destruct_n(m_begin + newSize, toShrink);
416  m_end = m_begin + newSize;
417  }
418  inline void move_down_1(iterator it, int_to_type<true> itt) {
419  internal::move(it + 1, m_end, it, itt);
420  }
421  inline void move_down_1(iterator it, int_to_type<false> itt) {
422  internal::copy(it + 1, m_end, it, itt);
423  }
424 
425  inline void move_down(iterator it_start, iterator it_result, int_to_type<true> itt) {
426  assert(it_start > it_result);
427  internal::move(it_start, m_end, it_result, itt);
428  }
429  inline void move_down(iterator it_start, iterator it_result, int_to_type<false> itt) {
430  assert(it_start > it_result);
431  internal::copy(it_start, m_end, it_result, itt);
432  }
433 
434 
435 
436  private:
437  using TStorage::m_begin;
438  using TStorage::m_end;
439  using TStorage::m_capacityEnd;
440  using TStorage::m_allocator;
441  using TStorage::invariant;
442  using TStorage::reallocate;
443  };
444 
445  template<typename T, class TAllocator = mn::memory::default_allocator,
446  class TStorage = basic_vector_storage<T, TAllocator> >
448  a.swap(b);
449  }
450 
451 
452  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
453  class TStorage = basic_vector_storage<T, TAllocator> >
457  int size = (calc != 0 ? calc : a.size());
458 
459  for(int i = 0; i < size; i++)
460  c.push_back(a[i] + b[i]);
461  return c;
462  }
463  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
464  class TStorage = basic_vector_storage<T, TAllocator> >
466  const T& b) {
468  int size = (calc != 0 ? calc : a.size());
469 
470  for(int i = 0; i < size; i++)
471  c.push_back(a[i] + b);
472  return c;
473  }
474 
475  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
476  class TStorage = basic_vector_storage<T, TAllocator> >
480  int size = (calc != 0 ? calc : b.size());
481 
482  for(int i = 0; i < size; i++)
483  c.push_back(a + b[i]);
484  return c;
485  }
486 
487  //sub ------
488  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
489  class TStorage = basic_vector_storage<T, TAllocator> >
493  int size = (calc != 0 ? calc : a.size());
494 
495  for(int i = 0; i < size; i++)
496  c.push_back(a[i] - b[i]);
497  return c;
498  }
499 
500  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
501  class TStorage = basic_vector_storage<T, TAllocator> >
504  int size = (calc != 0 ? calc : a.size());
505 
506  for(int i = 0; i < size; i++)
507  c.push_back(-a[i]);
508  return c;
509  }
510 
511  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
512  class TStorage = basic_vector_storage<T, TAllocator> >
514  const T& b) {
516  int size = (calc != 0 ? calc : a.size());
517 
518  for(int i = 0; i < size; i++)
519  c.push_back(a[i] - b);
520  return c;
521  }
522 
523  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
524  class TStorage = basic_vector_storage<T, TAllocator> >
528  int size = (calc != 0 ? calc : b.size());
529 
530  for(int i = 0; i < size; i++)
531  c.push_back(a - b[i]);
532  return c;
533  }
534 
535  //mul ----
536  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
537  class TStorage = basic_vector_storage<T, TAllocator> >
541  int size = (calc != 0 ? calc : a.size());
542 
543  for(int i = 0; i < size; i++)
544  c.push_back(a[i] * b[i]);
545  return c;
546  }
547  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
548  class TStorage = basic_vector_storage<T, TAllocator> >
550  const T& b) {
552  int size = (calc != 0 ? calc : a.size());
553 
554  for(int i = 0; i < size; i++)
555  c.push_back(a[i] * b);
556  return c;
557  }
558  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
559  class TStorage = basic_vector_storage<T, TAllocator> >
563  int size = (calc != 0 ? calc : b.size());
564 
565  for(int i = 0; i < size; i++)
566  c.push_back(a * b[i]);
567  return c;
568  }
569 
570  // div -----
571  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
572  class TStorage = basic_vector_storage<T, TAllocator> >
576  int size = (calc != 0 ? calc : a.size());
577 
578  for(int i = 0; i < size; i++)
579  c.push_back(a[i] / b[i]);
580  return c;
581  }
582 
583  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
584  class TStorage = basic_vector_storage<T, TAllocator> >
586  const T& b) {
588  int size = (calc != 0 ? calc : a.size());
589 
590  for(int i = 0; i < size; i++)
591  c.push_back(a[i] / b);
592  return c;
593  }
594 
595  template<typename T, int calc = 0, class TAllocator = mn::memory::default_allocator,
596  class TStorage = basic_vector_storage<T, TAllocator> >
600  int size = (calc != 0 ? calc : b.size());
601 
602  for(int i = 0; i < size; i++)
603  c.push_back(a / b[i]);
604  return c;
605  }
606 
607  // scale ----
608  template<typename T, class TAllocator = mn::memory::default_allocator,
609  class TStorage = basic_vector_storage<T, TAllocator> >
611  const T s) {
612  return v * s;
613  }
614 
615  template<typename T, class TAllocator = mn::memory::default_allocator,
616  class TStorage = basic_vector_storage<T, TAllocator> >
618  }
619 }
620 #endif
Definition: mn_vector.hpp:117
iterator insert(iterator it, const_reference val)
Definition: mn_vector.hpp:274
reference front()
Definition: mn_vector.hpp:183
const pointer const_iterator
Definition: mn_vector.hpp:128
const reference operator[](size_type i) const
Definition: mn_vector.hpp:397
void reset()
Definition: mn_vector.hpp:348
void resize(size_type n)
Definition: mn_vector.hpp:334
T value_type
Definition: mn_vector.hpp:121
iterator begin()
Definition: mn_vector.hpp:173
void move_down_1(iterator it, int_to_type< true > itt)
Definition: mn_vector.hpp:418
const T & const_reference
Definition: mn_vector.hpp:125
basic_vector(const basic_vector &rhs, const allocator_type &allocator=allocator_type())
Definition: mn_vector.hpp:144
iterator end()
Definition: mn_vector.hpp:174
size_type capacity()
Definition: mn_vector.hpp:179
const reference cfront()
Definition: mn_vector.hpp:184
size_type compute_new_capacity(size_type newMinCapacity) const
Definition: mn_vector.hpp:401
TAllocator allocator_type
Definition: mn_vector.hpp:129
void move_down(iterator it_start, iterator it_result, int_to_type< false > itt)
Definition: mn_vector.hpp:429
const allocator_type & get_allocator() const
Definition: mn_vector.hpp:377
void set_allocator(const allocator_type &allocator)
Definition: mn_vector.hpp:381
void move_down_1(iterator it, int_to_type< false > itt)
Definition: mn_vector.hpp:421
const reference cback()
Definition: mn_vector.hpp:186
static const size_type npos
Definition: mn_vector.hpp:132
reference operator[](size_type i)
Definition: mn_vector.hpp:393
reference at(size_type i)
Definition: mn_vector.hpp:188
basic_vector(const_iterator first, const_iterator last, const allocator_type &allocator=allocator_type())
Definition: mn_vector.hpp:141
iterator erase(iterator first, iterator last)
Definition: mn_vector.hpp:318
void insert(iterator it, size_type n, const reference val)
Definition: mn_vector.hpp:266
basic_vector(size_type initialSize, const allocator_type &allocator=allocator_type())
Definition: mn_vector.hpp:138
void push_back(const_reference v)
Definition: mn_vector.hpp:193
T && lreference
Definition: mn_vector.hpp:124
size_type size() const
Definition: mn_vector.hpp:176
void grow()
Definition: mn_vector.hpp:406
const reference const_at(size_type i)
Definition: mn_vector.hpp:189
mn::size_t size_type
Definition: mn_vector.hpp:130
pointer iterator
Definition: mn_vector.hpp:127
void push_back(lreference v)
Definition: mn_vector.hpp:197
iterator find(const reference item)
Definition: mn_vector.hpp:369
void reserve(size_type n)
Definition: mn_vector.hpp:339
basic_vector & operator=(const basic_vector &rhs)
Definition: mn_vector.hpp:389
void assign(const pointer first, const pointer last)
Definition: mn_vector.hpp:211
void copy(const basic_vector &rhs)
Definition: mn_vector.hpp:161
size_type index_of(const reference item, size_type index=0) const
Definition: mn_vector.hpp:357
bool validate_iterator(const_iterator it) const
Definition: mn_vector.hpp:385
void insert(size_type index, size_type n, const reference val)
Definition: mn_vector.hpp:228
pointer data()
Definition: mn_vector.hpp:181
reference back()
Definition: mn_vector.hpp:185
void set_capacity(size_type newCapacity)
Definition: mn_vector.hpp:353
void pop_back()
Definition: mn_vector.hpp:206
basic_vector(const allocator_type &allocator=allocator_type())
Definition: mn_vector.hpp:135
T * pointer
Definition: mn_vector.hpp:122
~basic_vector()
Definition: mn_vector.hpp:155
void push_back()
Definition: mn_vector.hpp:202
void shrink(size_type newSize)
Definition: mn_vector.hpp:412
bool empty() const
Definition: mn_vector.hpp:177
T & reference
Definition: mn_vector.hpp:123
static const size_type kInitialCapacity
Definition: mn_vector.hpp:133
void clear()
Definition: mn_vector.hpp:343
void move_down(iterator it_start, iterator it_result, int_to_type< true > itt)
Definition: mn_vector.hpp:425
mn::ptrdiff_t difference_type
Definition: mn_vector.hpp:126
iterator erase(iterator it)
Definition: mn_vector.hpp:306
basic_vector< T, TAllocator, TStorage > scale(const basic_vector< T, TAllocator, TStorage > &v, const T s)
Definition: mn_vector.hpp:610
void swap(basic_vector< T, TAllocator, TStorage > &a, basic_vector< T, TAllocator, TStorage > &b)
Definition: mn_vector.hpp:447
basic_tuple< N, T > operator+(const basic_tuple< N, T > &a, const basic_tuple< N, U > &b)
Definition: mn_tuple.hpp:272
void swap(basic_any &x, basic_any &y) noexcept
Definition: mn_any.hpp:272
basic_tuple< N, T > operator*(const basic_tuple< N, T > &a, const basic_tuple< N, U > &b)
Definition: mn_tuple.hpp:288
basic_tuple< N, T > operator-(const basic_tuple< N, T > &a, const basic_tuple< N, U > &b)
Definition: mn_tuple.hpp:280
basic_tuple< N, T > operator/(const basic_tuple< N, T > &a, const basic_tuple< N, U > &b)
Definition: mn_tuple.hpp:296
void move_n(const T *from, mn::size_t n, T *result, int_to_type< false >)
Definition: mn_utils.hpp:68
void move(const T *first, const T *last, T *result, int_to_type< false >)
Definition: mn_utils.hpp:79
void copy(const T *first, const T *last, T *result, int_to_type< false >)
Definition: mn_utils.hpp:56
struct mn::memory::detail::ptr_difference T
Definition: mn_atomic_singleton.hpp:38
malloc_allocator< basic_allocator_filter > default_allocator
Definition: mn_default_allocator.hpp:30
Definition: mn_allocator_typetraits.hpp:25
void move_n(const T *from, size_t n, T *dest)
Definition: mn_algorithm.hpp:89
void destruct_n(T *src, size_t n)
Definition: mn_algorithm.hpp:131
void swap(TAssignable &a, TAssignable &b)
Definition: mn_algorithm.hpp:312
void copy_construct(T *mem, const T &orig)
Definition: mn_algorithm.hpp:45
size_t alignment_for(const size_t size) noexcept
Definition: mn_alignment.hpp:178
long ptrdiff_t
Definition: mn_def.hpp:49
void copy_construct_n(T *src, size_t n, T *dest)
Definition: mn_algorithm.hpp:84
void construct(T *mem)
Definition: mn_algorithm.hpp:55
void move(const T *src, const T *last, T *dest)
Definition: mn_algorithm.hpp:100
void copy_n(const T *src, size_t n, T *dest)
Copy N elements from src to dest.
Definition: mn_algorithm.hpp:74
MN_THREAD_CONFIG_SIZE_TYPE size_t
Definition: mn_def.hpp:48
Definition: mn_vector.hpp:36
pointer m_begin
Definition: mn_vector.hpp:110
pointer m_capacityEnd
Definition: mn_vector.hpp:112
void reallocate_discard_old(size_type newCapacity)
Definition: mn_vector.hpp:66
allocator_type m_allocator
Definition: mn_vector.hpp:113
void reallocate(size_type newCapacity, size_type oldSize)
Definition: mn_vector.hpp:50
void destroy(pointer ptr, size_type n)
Definition: mn_vector.hpp:83
value_type & reference
Definition: mn_vector.hpp:41
T value_type
Definition: mn_vector.hpp:39
value_type * pointer
Definition: mn_vector.hpp:40
pointer m_end
Definition: mn_vector.hpp:111
T && lreference
Definition: mn_vector.hpp:42
void swap(self_type &other)
Definition: mn_vector.hpp:103
TAllocator allocator_type
Definition: mn_vector.hpp:37
mn::size_t size_type
Definition: mn_vector.hpp:43
bool invariant() const
Definition: mn_vector.hpp:99
void reset()
Definition: mn_vector.hpp:93
basic_vector_storage(const allocator_type &allocator)
Definition: mn_vector.hpp:47
Definition: mn_typetraits.hpp:365
Definition: mn_inttokey.hpp:25
Definition: mn_typetraits.hpp:159
Definition: mn_iterator.hpp:36