CppELib 1.7.0
Loading...
Searching...
No Matches
FixedDeque.h
Go to the documentation of this file.
1#ifndef CONTAINER_FIXED_DEQUE_H_INCLUDED
2#define CONTAINER_FIXED_DEQUE_H_INCLUDED
3
4#include <cstddef>
5#ifndef CPPELIB_NO_STD_ITERATOR
6#include <iterator>
7#endif
9#include "private/TypeTraits.h"
10#include "private/Construct.h"
11#include "Assertion/Assertion.h"
12
13namespace Container {
14
15template <typename T, std::size_t MaxSize>
16class FixedDeque;
17
21template <typename T, typename Ref, typename Ptr, typename DeqPtr, std::size_t MaxSize>
23public:
24 typedef T value_type;
25 typedef std::size_t size_type;
26 typedef std::ptrdiff_t difference_type;
29 typedef Ref reference;
30 typedef const Ref const_reference;
31 typedef Ptr pointer;
32 typedef const Ptr const_pointer;
33#ifndef CPPELIB_NO_STD_ITERATOR
34 typedef std::random_access_iterator_tag iterator_category;
35#endif
36
37 FixedDeque_iterator() : m_deq(0), m_idx(0U) {}
38
39 FixedDeque_iterator(const iterator& x) : m_deq(x.m_deq), m_idx(x.m_idx) {}
40
42 {
43 m_deq = x.m_deq;
44 m_idx = x.m_idx;
45 return *this;
46 }
47
49 {
50 DEBUG_ASSERT(m_deq != 0);
51 if (n < 0) {
52 return operator-=(-n);
53 }
54
55 const size_type un = static_cast<size_type>(n);
56 m_idx = m_deq->next_idx(m_idx, un);
57 return *this;
58 }
59
61 {
62 FixedDeque_iterator tmp = *this;
63 return tmp += n;
64 }
65
67 {
68 DEBUG_ASSERT(m_deq != 0);
69 if (n < 0) {
70 return operator+=(-n);
71 }
72
73 const size_type un = static_cast<size_type>(n);
74 m_idx = m_deq->prev_idx(m_idx, un);
75 return *this;
76 }
77
79 {
80 DEBUG_ASSERT(m_deq != 0);
81 DEBUG_ASSERT(m_deq == x.m_deq);
82 if (*this >= x) {
83 return static_cast<difference_type>(m_deq->distance_idx(x.m_idx, m_idx));
84 }
85 return -static_cast<difference_type>(m_deq->distance_idx(m_idx, x.m_idx));
86 }
87
89 {
90 FixedDeque_iterator tmp = *this;
91 return tmp -= n;
92 }
93
95 {
96 return operator+=(1);
97 }
98
100 {
101 return operator-=(1);
102 }
103
105 {
106 FixedDeque_iterator tmp = *this;
107 ++*this;
108 return tmp;
109 }
110
112 {
113 FixedDeque_iterator tmp = *this;
114 --*this;
115 return tmp;
116 }
117
119 {
120 DEBUG_ASSERT(m_deq != 0);
121 return m_deq->m_virtualBuf[m_idx];
122 }
123
125 {
126 DEBUG_ASSERT(m_deq != 0);
127 return &m_deq->m_virtualBuf[m_idx];
128 }
129
131 {
132 return *(*this + n);
133 }
134
135 bool operator==(const FixedDeque_iterator& x) const
136 {
137 return (m_deq == x.m_deq) && (m_idx == x.m_idx);
138 }
139
140 bool operator!=(const FixedDeque_iterator& x) const
141 {
142 return !(*this == x);
143 }
144
145 bool operator<(const FixedDeque_iterator& x) const
146 {
147 DEBUG_ASSERT(m_deq != 0);
148 DEBUG_ASSERT(m_deq == x.m_deq);
149 return
150 m_deq->distance_idx(m_deq->m_begin, m_idx) <
151 m_deq->distance_idx(x.m_deq->m_begin, x.m_idx);
152 }
153
154 bool operator>(const FixedDeque_iterator& x) const
155 {
156 return x < *this;
157 }
158
159 bool operator<=(const FixedDeque_iterator& x) const
160 {
161 return !(x < *this);
162 }
163
164 bool operator>=(const FixedDeque_iterator& x) const
165 {
166 return !(*this < x);
167 }
168
169private:
170 template <typename U, std::size_t N>
171 friend class FixedDeque;
172
173 template <typename U, typename RefX, typename PtrX, typename DeqPtrX, std::size_t N>
175
176 DeqPtr m_deq;
177 size_type m_idx;
178
179 FixedDeque_iterator(DeqPtr deq, size_type idx) : m_deq(deq), m_idx(idx) {}
180};
181
182template <typename T, typename Ref, typename Ptr, typename DeqPtr, std::size_t MaxSize>
183FixedDeque_iterator<T, Ref, Ptr, DeqPtr, MaxSize>
185{
186 return x + n;
187}
188
200template <typename T, std::size_t MaxSize>
202public:
203 typedef T value_type;
204 typedef std::size_t size_type;
205 typedef std::ptrdiff_t difference_type;
211 typedef const value_type* const_pointer;
212#ifndef CPPELIB_NO_STD_ITERATOR
213 typedef std::reverse_iterator<iterator> reverse_iterator;
214 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
215#endif
216
217private:
218 static const size_type BufSize = MaxSize + 1U;
219
220 union InternalBuf {
221 double dummyForAlignment;
222 char buf[sizeof(T) * BufSize];
223 };
224 InternalBuf m_realBuf;
225 T (&m_virtualBuf)[BufSize];
226 size_type m_begin;
227 size_type m_end;
228
229 class BadAlloc : public Container::BadAlloc {
230 public:
231 BadAlloc() : Container::BadAlloc() {}
232 const char* what() const CPPELIB_CONTAINER_NOEXCEPT
233 {
234 return "FixedDeque::BadAlloc";
235 }
236 };
237
238public:
240 : m_realBuf(), m_virtualBuf(*reinterpret_cast<T(*)[BufSize]>(&m_realBuf)), m_begin(0U), m_end(0U)
241 {}
242
243 explicit FixedDeque(size_type n, const T& data = T())
244 : m_realBuf(), m_virtualBuf(*reinterpret_cast<T(*)[BufSize]>(&m_realBuf)), m_begin(0U), m_end(0U)
245 {
246 assign(n, data);
247 }
248
249 template <typename InputIterator>
251 : m_realBuf(), m_virtualBuf(*reinterpret_cast<T(*)[BufSize]>(&m_realBuf)), m_begin(0U), m_end(0U)
252 {
253 assign(first, last);
254 }
255
257 : m_realBuf(), m_virtualBuf(*reinterpret_cast<T(*)[BufSize]>(&m_realBuf)), m_begin(0U), m_end(0U)
258 {
259 assign(x.begin(), x.end());
260 }
261
263 {
264 destroy_range(begin(), end());
265 }
266
268 {
269 if (this != &x) {
270 assign(x.begin(), x.end());
271 }
272 return *this;
273 }
274
276 {
277 return distance_idx(m_begin, m_end);
278 }
279
281 {
282 return MaxSize;
283 }
284
286 {
287 return max_size() - size();
288 }
289
290 bool empty() const
291 {
292 return m_begin == m_end;
293 }
294
295 bool full() const
296 {
297 return size() == max_size();
298 }
299
300 void clear()
301 {
302 destroy_range(begin(), end());
303 m_end = m_begin;
304 }
305
307 {
308 return *(begin() + idx);
309 }
310
312 {
313 return *(begin() + idx);
314 }
315
317 {
318 if (idx >= size()) {
319 CPPELIB_CONTAINER_THROW(OutOfRange("FixedDeque::at"));
320 }
321 return *(begin() + idx);
322 }
323
325 {
326 if (idx >= size()) {
327 CPPELIB_CONTAINER_THROW(OutOfRange("FixedDeque::at"));
328 }
329 return *(begin() + idx);
330 }
331
333 {
334 return iterator(this, m_begin);
335 }
336
338 {
339 return const_iterator(this, m_begin);
340 }
341
343 {
344 return iterator(this, m_end);
345 }
346
348 {
349 return const_iterator(this, m_end);
350 }
351
352#ifndef CPPELIB_NO_STD_ITERATOR
354 {
355 return reverse_iterator(end());
356 }
357
359 {
360 return const_reverse_iterator(end());
361 }
362
364 {
365 return reverse_iterator(begin());
366 }
367
369 {
371 }
372#endif
373
375 {
377 return *begin();
378 }
379
381 {
383 return *begin();
384 }
385
387 {
389 return *(end() - 1);
390 }
391
393 {
395 return *(end() - 1);
396 }
397
398 void resize(size_type n, const T& data = T())
399 {
400 if (size() >= n) {
401 destroy_range(begin() + n, end());
402 m_end = prev_idx(m_end, size() - n);
403 return;
404 }
405
406 if (max_size() < n) {
407 CPPELIB_CONTAINER_THROW(BadAlloc());
408 }
409 const size_type rest = n - size();
410 for (size_type i = 0U; i < rest; ++i) {
411 push_back(data);
412 }
413 }
414
415 void push_back(const T& data)
416 {
417 if (full()) {
418 CPPELIB_CONTAINER_THROW(BadAlloc());
419 }
420 construct(&*end(), data);
421 m_end = next_idx(m_end);
422 }
423
424 void pop_back()
425 {
427 destroy(&*(end() - 1));
428 m_end = prev_idx(m_end);
429 }
430
431 void push_front(const T& data)
432 {
433 if (full()) {
434 CPPELIB_CONTAINER_THROW(BadAlloc());
435 }
436 construct(&*(begin() - 1), data);
437 m_begin = prev_idx(m_begin);
438 }
439
441 {
443 destroy(&*begin());
444 m_begin = next_idx(m_begin);
445 }
446
447 void assign(size_type n, const T& data)
448 {
449 if (max_size() < n) {
450 CPPELIB_CONTAINER_THROW(BadAlloc());
451 }
452 clear();
453 resize(n, data);
454 }
455
456 template <typename InputIterator>
458 {
459 size_type n = 0U;
460 for (InputIterator i = first; i != last; ++i) {
461 ++n;
462 }
463 if (max_size() < n) {
464 CPPELIB_CONTAINER_THROW(BadAlloc());
465 }
466 clear();
467 for (; first != last; ++first) {
469 }
470 }
471
473 {
474 DEBUG_ASSERT((begin() <= pos) && (pos <= end()));
475 return insert_n(pos, 1U, data);
476 }
477
478 void insert(iterator pos, size_type n, const T& data)
479 {
480 DEBUG_ASSERT((begin() <= pos) && (pos <= end()));
481 insert_n(pos, n, data);
482 }
483
484 template <typename InputIterator>
486 {
487 DEBUG_ASSERT((begin() <= pos) && (pos <= end()));
489 insert_dispatch(pos, first, last, Integral());
490 }
491
493 {
494 DEBUG_ASSERT((begin() <= pos) && (pos < end()));
495 return erase(pos, pos + 1);
496 }
497
499 {
501 DEBUG_ASSERT((begin() <= first) && (first < end()));
502 DEBUG_ASSERT((begin() <= last) && (last <= end()));
503 const size_type n = static_cast<size_type>(last - first);
504 if ((first - begin()) >= (end() - last)) {
505 // move the end side
506 for (iterator i = last; i != end(); ++i) {
507 *(i - n) = *i;
508 }
509 destroy_range(end() - n, end());
510 m_end = prev_idx(m_end, n);
511 return first;
512 } else {
513 // move the begin side
514 iterator stop = begin() - 1;
515 for (iterator i = first - 1; i != stop; --i) {
516 *(i + n) = *i;
517 }
518 destroy_range(begin(), begin() + n);
519 m_begin = next_idx(m_begin, n);
520 return last;
521 }
522 }
523
524private:
525 template <typename U, typename Ref, typename Ptr, typename DeqPtr, std::size_t N>
527
528 template <typename U, std::size_t N>
529 friend bool operator==(const FixedDeque<U, N>& x, const FixedDeque<U, N>& y);
530
531 size_type next_idx(size_type idx, size_type un = 1U) const
532 {
533 if (idx + un < BufSize) {
534 return idx + un;
535 }
536 // wraparound
537 return idx + un - BufSize;
538 }
539
540 size_type prev_idx(size_type idx, size_type un = 1U) const
541 {
542 if (idx >= un) {
543 return idx - un;
544 }
545 // wraparound
546 return BufSize + idx - un;
547 }
548
549 size_type distance_idx(size_type first_idx, size_type last_idx) const
550 {
551 if (first_idx <= last_idx) {
552 return last_idx - first_idx;
553 }
554 // wraparound
555 return BufSize - first_idx + last_idx;
556 }
557
558 template <typename Integer>
559 void insert_dispatch(iterator pos, Integer n, Integer data, TrueType)
560 {
561 insert_n(pos, static_cast<size_type>(n), static_cast<T>(data));
562 }
563
564 template <typename InputIterator>
566 {
567 insert_range(pos, first, last);
568 }
569
570 iterator insert_n(iterator pos, size_type n, const T& data)
571 {
572 if (available_size() < n) {
573 CPPELIB_CONTAINER_THROW(BadAlloc());
574 }
575
576 if ((size() / 2U) < static_cast<size_type>(pos - begin())) {
577 // move the end side
579 iterator old_end = end();
580 if (num_elems_pos_to_end > n) {
581 for (size_type i = 0U; i < n; ++i) {
582 construct(&*end());
583 m_end = next_idx(m_end);
584 }
585 for (iterator it = old_end - 1; it != pos - 1; --it) {
586 *(it + n) = *it;
587 }
588 for (iterator it = pos; it != pos + n; ++it) {
589 *it = data;
590 }
591 } else {
592 for (size_type i = 0U; i < n - num_elems_pos_to_end; ++i) {
593 construct(&*end(), data);
594 m_end = next_idx(m_end);
595 }
596 for (iterator it = pos; it != pos + num_elems_pos_to_end; ++it) {
597 construct(&*end(), *it);
598 m_end = next_idx(m_end);
599 }
600 for (iterator it = pos; it != old_end; ++it) {
601 *it = data;
602 }
603 }
604 return pos;
605 } else {
606 // move the begin side
609 if (num_elems_beg_to_pos > n) {
610 for (size_type i = 0U; i < n; ++i) {
611 construct(&*(begin() - 1));
612 m_begin = prev_idx(m_begin);
613 }
614 for (iterator it = old_begin; it != pos; ++it) {
615 *(it - n) = *it;
616 }
617 for (iterator it = pos - n; it != pos; ++it) {
618 *it = data;
619 }
620 } else {
621 for (size_type i = 0U; i < n - num_elems_beg_to_pos; ++i) {
622 construct(&*(begin() - 1), data);
623 m_begin = prev_idx(m_begin);
624 }
625 for (iterator it = pos - 1; it != old_begin - 1; --it) {
626 construct(&*(begin() - 1), *it);
627 m_begin = prev_idx(m_begin);
628 }
629 for (iterator it = old_begin; it != pos; ++it) {
630 *it = data;
631 }
632 }
633 return pos - n;
634 }
635 }
636
637 template <typename InputIterator>
638 void insert_range(iterator pos, InputIterator first, InputIterator last)
639 {
640 size_type n = 0U;
641 for (InputIterator i = first; i != last; ++i) {
642 ++n;
643 }
644 if (available_size() < n) {
645 CPPELIB_CONTAINER_THROW(BadAlloc());
646 }
647
648 if ((size() / 2U) < static_cast<size_type>(pos - begin())) {
649 // move the end side
651 iterator old_end = end();
652 if (num_elems_pos_to_end > n) {
653 for (size_type i = 0U; i < n; ++i) {
654 construct(&*end());
655 m_end = next_idx(m_end);
656 }
657 for (iterator it = old_end - 1; it != pos - 1; --it) {
658 *(it + n) = *it;
659 }
660 for (; first != last; ++pos, ++first) {
661 *pos = *first;
662 }
663 } else {
665 for (size_type i = 0U; i < num_elems_pos_to_end; ++i) {
666 ++mid;
667 }
668 for (size_type i = 0U; i < n - num_elems_pos_to_end; ++i) {
669 construct(&*end(), *mid);
670 ++mid;
671 m_end = next_idx(m_end);
672 }
673 for (iterator it = pos; it != pos + num_elems_pos_to_end; ++it) {
674 construct(&*end(), *it);
675 m_end = next_idx(m_end);
676 }
677 for (iterator it = pos; it != old_end; ++it, ++first) {
678 *it = *first;
679 }
680 }
681 } else {
682 // move the begin side
685 if (num_elems_beg_to_pos > n) {
686 for (size_type i = 0U; i < n; ++i) {
687 construct(&*(begin() - 1));
688 m_begin = prev_idx(m_begin);
689 }
690 for (iterator it = old_begin; it != pos; ++it) {
691 *(it - n) = *it;
692 }
693 for (iterator it = pos - n; it != pos; ++it, ++first) {
694 *it = *first;
695 }
696 } else {
698 for (size_type i = 0U; i < n - num_elems_beg_to_pos; ++i) {
699 ++mid;
700 }
702 for (size_type i = 0U; i < n - num_elems_beg_to_pos; ++i) {
703 construct(&*(begin() - 1), *--p);
704 m_begin = prev_idx(m_begin);
705 }
706 for (iterator it = pos - 1; it != old_begin - 1; --it) {
707 construct(&*(begin() - 1), *it);
708 m_begin = prev_idx(m_begin);
709 }
710 for (iterator it = old_begin; it != pos; ++it, ++mid) {
711 *it = *mid;
712 }
713 }
714 }
715 }
716
717};
718
719template <typename T, std::size_t MaxSize>
721{
722 if (x.size() != y.size()) {
723 return false;
724 }
725 for (std::size_t i = 0U; i < x.size(); ++i) {
726 if (!(x[i] == y[i])) {
727 return false;
728 }
729 }
730 return true;
731}
732
733template <typename T, std::size_t MaxSize>
735{
736 return !(x == y);
737}
738
739}
740
741#endif // CONTAINER_FIXED_DEQUE_H_INCLUDED
#define DEBUG_ASSERT(x)
The same as CHECK_ASSERT() macro.
Definition Assertion.h:39
Definition ContainerException.h:34
Random-access iterator used as FixedDeque<T, MaxSize>::iterator or FixedDeque<T, MaxSize>::const_iter...
Definition FixedDeque.h:22
bool operator>=(const FixedDeque_iterator &x) const
Definition FixedDeque.h:164
FixedDeque_iterator operator--(int)
Definition FixedDeque.h:111
const Ref const_reference
Definition FixedDeque.h:30
reference operator*() const
Definition FixedDeque.h:118
bool operator<(const FixedDeque_iterator &x) const
Definition FixedDeque.h:145
bool operator!=(const FixedDeque_iterator &x) const
Definition FixedDeque.h:140
FixedDeque_iterator & operator--()
Definition FixedDeque.h:99
pointer operator->() const
Definition FixedDeque.h:124
reference operator[](difference_type n) const
Definition FixedDeque.h:130
const Ptr const_pointer
Definition FixedDeque.h:32
difference_type operator-(const FixedDeque_iterator &x) const
Definition FixedDeque.h:78
bool operator==(const FixedDeque_iterator &x) const
Definition FixedDeque.h:135
Ref reference
Definition FixedDeque.h:29
FixedDeque_iterator & operator-=(difference_type n)
Definition FixedDeque.h:66
FixedDeque_iterator & operator=(const iterator &x)
Definition FixedDeque.h:41
FixedDeque_iterator< T, T &, T *, FixedDeque< T, MaxSize > *, MaxSize > iterator
Definition FixedDeque.h:27
FixedDeque_iterator operator+(difference_type n) const
Definition FixedDeque.h:60
FixedDeque_iterator & operator++()
Definition FixedDeque.h:94
FixedDeque_iterator operator++(int)
Definition FixedDeque.h:104
FixedDeque_iterator & operator+=(difference_type n)
Definition FixedDeque.h:48
friend class FixedDeque_iterator
Definition FixedDeque.h:174
FixedDeque_iterator operator-(difference_type n) const
Definition FixedDeque.h:88
FixedDeque_iterator(const iterator &x)
Definition FixedDeque.h:39
T value_type
Definition FixedDeque.h:24
std::size_t size_type
Definition FixedDeque.h:25
Ptr pointer
Definition FixedDeque.h:31
FixedDeque_iterator< T, const T &, const T *, const FixedDeque< T, MaxSize > *, MaxSize > const_iterator
Definition FixedDeque.h:28
std::random_access_iterator_tag iterator_category
Definition FixedDeque.h:34
bool operator>(const FixedDeque_iterator &x) const
Definition FixedDeque.h:154
FixedDeque_iterator()
Definition FixedDeque.h:37
bool operator<=(const FixedDeque_iterator &x) const
Definition FixedDeque.h:159
std::ptrdiff_t difference_type
Definition FixedDeque.h:26
STL-like deque container with fixed capacity.
Definition FixedDeque.h:201
void insert(iterator pos, InputIterator first, InputIterator last)
Definition FixedDeque.h:485
value_type & reference
Definition FixedDeque.h:208
void clear()
Definition FixedDeque.h:300
void push_back(const T &data)
Definition FixedDeque.h:415
size_type max_size() const
Definition FixedDeque.h:280
std::reverse_iterator< iterator > reverse_iterator
Definition FixedDeque.h:213
const_reference operator[](size_type idx) const
Definition FixedDeque.h:311
std::size_t size_type
Definition FixedDeque.h:204
const value_type * const_pointer
Definition FixedDeque.h:211
FixedDeque(InputIterator first, InputIterator last)
Definition FixedDeque.h:250
size_type available_size() const
Definition FixedDeque.h:285
void insert(iterator pos, size_type n, const T &data)
Definition FixedDeque.h:478
const_reverse_iterator rend() const
Definition FixedDeque.h:368
const_iterator begin() const
Definition FixedDeque.h:337
void assign(InputIterator first, InputIterator last)
Definition FixedDeque.h:457
iterator erase(iterator pos)
Definition FixedDeque.h:492
const_reference back() const
Definition FixedDeque.h:392
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition FixedDeque.h:214
const_reverse_iterator rbegin() const
Definition FixedDeque.h:358
~FixedDeque()
Definition FixedDeque.h:262
const_iterator end() const
Definition FixedDeque.h:347
reverse_iterator rend()
Definition FixedDeque.h:363
iterator begin()
Definition FixedDeque.h:332
FixedDeque()
Definition FixedDeque.h:239
FixedDeque & operator=(const FixedDeque &x)
Definition FixedDeque.h:267
reference operator[](size_type idx)
Definition FixedDeque.h:306
void push_front(const T &data)
Definition FixedDeque.h:431
reverse_iterator rbegin()
Definition FixedDeque.h:353
FixedDeque_iterator< T, T &, T *, FixedDeque *, MaxSize > iterator
Definition FixedDeque.h:206
std::ptrdiff_t difference_type
Definition FixedDeque.h:205
iterator end()
Definition FixedDeque.h:342
FixedDeque(size_type n, const T &data=T())
Definition FixedDeque.h:243
const_reference at(size_type idx) const
Definition FixedDeque.h:324
iterator insert(iterator pos, const T &data)
Definition FixedDeque.h:472
iterator erase(iterator first, iterator last)
Definition FixedDeque.h:498
value_type * pointer
Definition FixedDeque.h:210
const_reference front() const
Definition FixedDeque.h:380
void pop_front()
Definition FixedDeque.h:440
reference at(size_type idx)
Definition FixedDeque.h:316
bool full() const
Definition FixedDeque.h:295
reference front()
Definition FixedDeque.h:374
FixedDeque_iterator< T, const T &, const T *, const FixedDeque *, MaxSize > const_iterator
Definition FixedDeque.h:207
bool empty() const
Definition FixedDeque.h:290
friend bool operator==(const FixedDeque< U, N > &x, const FixedDeque< U, N > &y)
reference back()
Definition FixedDeque.h:386
void assign(size_type n, const T &data)
Definition FixedDeque.h:447
FixedDeque(const FixedDeque &x)
Definition FixedDeque.h:256
void resize(size_type n, const T &data=T())
Definition FixedDeque.h:398
size_type size() const
Definition FixedDeque.h:275
void pop_back()
Definition FixedDeque.h:424
T value_type
Definition FixedDeque.h:203
const value_type & const_reference
Definition FixedDeque.h:209
Definition ContainerException.h:23
Definition Array.h:10
FixedDeque_iterator< T, Ref, Ptr, DeqPtr, MaxSize > operator+(std::ptrdiff_t n, const FixedDeque_iterator< T, Ref, Ptr, DeqPtr, MaxSize > &x)
Definition FixedDeque.h:184
bool operator==(const Array< T, Size > &x, const Array< T, Size > &y)
Definition Array.h:160
bool operator!=(const Array< T, Size > &x, const Array< T, Size > &y)
Definition Array.h:171