70 #define XSARRAY_DECL(T)\
72 const XsSize m_size; \
73 const XsSize m_reserved; \
74 const XsSize m_flags; \
75 XsArrayDescriptor const* const m_descriptor;
77 #define XSARRAY_STRUCT(S,T) struct S { XSARRAY_DECL(T) }
78 #define XSARRAY_INITIALIZER(D) { 0, 0, 0, XSDF_Managed, D }
81 typedef void (*XsArrayItemSwapFunc)(
void*,
void*);
82 typedef void (*XsArrayItemStructFunc)(
void*);
83 typedef void (*XsArrayItemCopyFunc)(
void*,
void const*);
84 typedef int (*XsArrayItemCompareFunc)(
void const*,
void const*);
85 typedef void (*XsArrayRawCopy)(
void*,
void const*,
XsSize,
XsSize);
87 #define XSEXPCASTITEMSWAP (XsArrayItemSwapFunc)
88 #define XSEXPCASTITEMMAKE (XsArrayItemStructFunc)
89 #define XSEXPCASTITEMCOPY (XsArrayItemCopyFunc)
90 #define XSEXPCASTITEMCOMP (XsArrayItemCompareFunc)
91 #define XSEXPCASTRAWCOPY (XsArrayRawCopy)
104 template <
typename T, XsArrayDescriptor const& D,
typename I>
friend struct XsArrayImpl;
121 #if __cplusplus >= 201103L && !defined(XSENS_HAVE_TYPE_TRAITS)
122 #include <type_traits>
123 #define XSENS_HAVE_TYPE_TRAITS
186 , m_descriptor(descriptor)
197 , m_descriptor(src.m_descriptor)
236 template <
typename T, XsArrayDescriptor const& D,
typename I>
237 struct XsArrayImpl :
private XsArray
240 typedef T value_type;
246 typedef XsArrayImpl<T, D, I> ArrayImpl;
253 inline explicit XsArrayImpl<T, D, I>(
XsSize count = 0, T
const* src = 0)
259 inline XsArrayImpl<T, D, I>(ArrayImpl
const& other)
264 #ifndef XSENS_NOITERATOR
265 template <
typename Iterator>
267 inline explicit XsArrayImpl<T, D, I>(Iterator
const& beginIt, Iterator
const& endIt)
270 ptrdiff_t diff = endIt - beginIt;
274 for (Iterator it = beginIt; it != endIt; ++it)
286 inline ~XsArrayImpl()
304 inline int comparePredicate(ArrayImpl
const& other, XsArrayItemCompareFunc predicate)
const
315 inline bool isEqualPredicate(ArrayImpl
const& other, XsArrayItemCompareFunc predicate)
const
326 inline bool operator == (ArrayImpl
const& other)
const
336 inline bool operator != (ArrayImpl
const& other)
const
342 inline void reserve(
XsSize count)
348 inline XsSize reserved()
const
356 return *m_descriptor;
360 #ifndef XSENS_NOITERATOR
362 template <ptrdiff_t F,
typename R,
typename Derived>
363 struct IteratorImplBase
367 typedef ptrdiff_t difference_type;
369 typedef T value_type;
373 typedef T& reference;
375 typedef std::random_access_iterator_tag iterator_category;
378 typedef Derived this_type;
381 static const ptrdiff_t direction = F;
384 inline explicit IteratorImplBase(
void* p = 0) : m_ptr((T*) p) {}
386 inline explicit IteratorImplBase(T* p) : m_ptr(p) {}
388 inline IteratorImplBase(this_type
const& i) : m_ptr(i.m_ptr) {}
392 template <
typename J>
393 inline T
const& operator[](J index)
const
395 #ifdef XSENS_HAVE_TYPE_TRAITS
396 static_assert(std::is_integral<J>::value || std::is_enum<J>::value,
"Integral index required.");
398 return *ptrAt(m_ptr, F *
static_cast<ptrdiff_t
>(index));
401 template <
typename J>
402 inline T& operator[](J index)
404 #ifdef XSENS_HAVE_TYPE_TRAITS
405 static_assert(std::is_integral<J>::value || std::is_enum<J>::value,
"Integral index required.");
407 return *ptrAt(m_ptr, F *
static_cast<ptrdiff_t
>(index));
411 inline T
const& operator[](
int index)
const
413 return *ptrAt(m_ptr, F *
static_cast<ptrdiff_t
>(index));
416 inline T& operator[](
int index)
418 return *ptrAt(m_ptr, F *
static_cast<ptrdiff_t
>(index));
421 inline this_type& operator =(
void* p)
425 return *(this_type*)
this;
428 inline this_type& operator =(T* p)
431 return *(this_type*)
this;
434 inline this_type& operator =(this_type
const& i)
437 return *(this_type*)
this;
440 inline this_type& operator ++()
442 m_ptr = (T*) ptrAt(m_ptr, F);
443 return *(this_type*)
this;
446 inline this_type operator ++(
int)
449 m_ptr = (T*) ptrAt(m_ptr, F);
453 inline this_type& operator --()
455 m_ptr = (T*) ptrAt(m_ptr, -F);
456 return *(this_type*)
this;
459 inline this_type operator --(
int)
462 m_ptr = (T*) ptrAt(m_ptr, -F);
466 inline this_type
const& operator +=(ptrdiff_t count)
468 m_ptr = ptrAt(m_ptr, F * count);
469 return *(this_type*)
this;
472 inline this_type
const& operator -=(ptrdiff_t count)
474 m_ptr = ptrAt(m_ptr, -F * count);
475 return *(this_type*)
this;
478 inline this_type operator +(ptrdiff_t count)
const
480 return this_type(ptrAt(m_ptr, F * count));
483 inline this_type operator -(ptrdiff_t count)
const
485 return this_type(ptrAt(m_ptr, -F * count));
494 inline difference_type operator - (
const this_type& other)
const
496 return (F * (
reinterpret_cast<char*
>(m_ptr) -
reinterpret_cast<char*
>(other.m_ptr))) / D.itemSize;
501 return m_ptr == i.m_ptr;
504 inline bool operator <= (this_type
const& i)
const
506 return (F == 1) ? (m_ptr <= i.m_ptr) : (m_ptr >= i.m_ptr);
509 inline bool operator < (this_type
const& i)
const
511 return (F == 1) ? (m_ptr < i.m_ptr) : (m_ptr > i.m_ptr);
514 inline bool operator != (this_type
const& i)
const
516 return m_ptr != i.m_ptr;
519 inline bool operator >= (this_type
const& i)
const
521 return (F == 1) ? (m_ptr >= i.m_ptr) : (m_ptr <= i.m_ptr);
524 inline bool operator > (this_type
const& i)
const
526 return (F == 1) ? (m_ptr > i.m_ptr) : (m_ptr < i.m_ptr);
529 inline R& operator *()
const
534 inline R* operator ->()
const
539 inline T* ptr()
const
550 #ifndef XSENS_NOITERATOR
552 template <ptrdiff_t F>
553 struct IteratorImpl :
public IteratorImplBase<F, T, IteratorImpl<F> >
557 typedef IteratorImplBase<F, T, IteratorImpl<F> > ParentType;
560 inline IteratorImpl(
void* p = 0) : ParentType(p) {}
562 inline IteratorImpl(T* p) : ParentType(p) {}
564 inline IteratorImpl(
const IteratorImpl& i) : ParentType(i) {}
568 template <ptrdiff_t F>
569 struct IteratorImplConst :
public IteratorImplBase<F, T const, IteratorImplConst<F> >
573 typedef IteratorImplBase<F, T const, IteratorImplConst<F> > ParentType;
576 inline IteratorImplConst(
void* p = 0) : ParentType(p) {}
578 inline IteratorImplConst(T* p) : ParentType(p) {}
580 inline IteratorImplConst(IteratorImpl<F>
const& i) : ParentType(i.ptr()) {}
582 inline IteratorImplConst(IteratorImplConst
const& i) : ParentType(i) {}
586 typedef IteratorImpl<1> iterator;
588 typedef IteratorImpl < -1 > reverse_iterator;
590 typedef IteratorImplConst<1> const_iterator;
592 typedef IteratorImplConst < -1 > const_reverse_iterator;
595 inline const_iterator begin()
const
597 return const_iterator(m_data);
600 inline const_iterator end()
const
602 return begin() + (ptrdiff_t) size();
606 inline const_reverse_iterator rbegin()
const
608 return rend() - (ptrdiff_t) size();
611 inline const_reverse_iterator rend()
const
613 return const_reverse_iterator(m_data) + (ptrdiff_t) 1;
617 inline iterator begin()
619 return iterator(m_data);
622 inline iterator end()
624 return begin() + (ptrdiff_t) size();
628 inline reverse_iterator rbegin()
630 return rend() - (ptrdiff_t) size();
633 inline reverse_iterator rend()
635 return reverse_iterator(m_data) + (ptrdiff_t) 1;
640 template <
typename J>
641 inline T
const& operator[](J index)
const
643 #ifdef XSENS_HAVE_TYPE_TRAITS
644 static_assert(std::is_integral<J>::value || std::is_enum<J>::value,
"Integral index required.");
646 assert(
static_cast<XsSize>(index) < m_size);
647 return *ptrAt(m_data,
static_cast<ptrdiff_t
>(index));
650 template <
typename J>
651 inline T& operator[](J index)
653 #ifdef XSENS_HAVE_TYPE_TRAITS
654 static_assert(std::is_integral<J>::value || std::is_enum<J>::value,
"Integral index required.");
656 assert(
static_cast<XsSize>(index) < m_size);
657 return *ptrAt(m_data,
static_cast<ptrdiff_t
>(index));
661 inline T
const& operator[](
int index)
const
663 assert(
static_cast<XsSize>(index) < m_size);
664 return *ptrAt(m_data,
static_cast<ptrdiff_t
>(index));
667 inline T& operator[](
int index)
669 assert(
static_cast<XsSize>(index) < m_size);
670 return *ptrAt(m_data,
static_cast<ptrdiff_t
>(index));
675 inline T value(
XsSize index)
const
677 #ifdef XSENS_NO_EXCEPTIONS
678 assert(index >= m_size);
681 throw std::out_of_range(
"index out of range");
683 return *ptrAt(m_data, index);
686 inline T first()
const
688 #ifdef XSENS_NO_EXCEPTIONS
692 throw std::out_of_range(
"out of range");
694 return *ptrAt(m_data, 0);
697 inline T last()
const
699 #ifdef XSENS_NO_EXCEPTIONS
703 throw std::out_of_range(
"out of range");
705 return *ptrAt(m_data, m_size - 1);
708 inline T
const& at(
XsSize index)
const
710 #ifdef XSENS_NO_EXCEPTIONS
711 assert(index >= m_size);
714 throw std::out_of_range(
"index out of range");
716 return *ptrAt(m_data, (ptrdiff_t) index);
719 inline T& at(
XsSize index)
721 #ifdef XSENS_NO_EXCEPTIONS
722 assert(index >= m_size);
725 throw std::out_of_range(
"index out of range");
727 return *ptrAt(m_data, index);
734 inline void insert(T
const& item,
XsSize index)
736 insert(&item, index, 1);
744 inline void insert(T
const* items,
XsSize index,
XsSize count)
749 #ifndef XSENS_NOITERATOR
755 inline void insert(T
const& item, const_iterator it)
757 insert(&item, indexOf(it), 1);
764 inline void insert(T
const& item, const_reverse_iterator it)
766 insert(&item, indexOf(it), 1);
775 inline void insert(T
const* items, const_iterator it,
XsSize count)
777 insert(items, indexOf(it), count);
785 inline void insert(T
const* items, const_reverse_iterator it,
XsSize count)
787 insert(items, indexOf(it), count);
792 inline void push_back(T
const& item)
794 insert(&item, (
XsSize) - 1, 1);
797 inline void pop_back(
XsSize count = 1)
802 erase(size() - count, count);
805 inline void push_front(T
const& item)
810 inline void pop_front(
XsSize count = 1)
818 inline XsSize size() const noexcept
827 #ifndef XSENS_NOITERATOR
829 inline iterator erase(iterator it)
833 return (idx < size()) ? ptrAt(m_data, idx) : end();
836 inline reverse_iterator erase(reverse_iterator it)
840 return (idx < size()) ? ptrAt(m_data, idx) : rend();
844 inline void assign(
XsSize count, T
const* src)
849 inline void resize(
XsSize count)
858 inline void setSize(
XsSize count)
864 inline void append(ArrayImpl
const& other)
869 inline ArrayImpl& operator=(ArrayImpl
const& other)
876 inline bool empty() const noexcept
878 return (size() == 0) || (m_data == 0) || (m_flags &
XSDF_Empty);
881 #ifndef XSENS_NOITERATOR
883 inline I
const& inherited()
const
885 return *
static_cast<I const*
>(
this);
889 inline I& inherited()
891 return *
static_cast<I*
>(
this);
896 inline void swap(ArrayImpl& other)
902 friend void swap(ArrayImpl& first, ArrayImpl& second)
911 if (a >= size() || b >= size())
923 #ifndef XSENS_NOITERATOR
932 inline ptrdiff_t find(T
const& needle)
const
938 inline ptrdiff_t findPredicate(T
const& needle, XsArrayItemCompareFunc predicate)
const
943 #ifndef XSENS_NOITERATOR
949 template <ptrdiff_t F,
typename R,
typename Derived>
950 XsSize indexOf(IteratorImplBase<F, R, Derived>
const& it)
const
952 ptrdiff_t
d = ((
char const*) it.ptr() - (
char const*) m_data);
965 inline void removeDuplicates()
971 inline void removeDuplicatesPredicate(XsArrayItemCompareFunc predicate)
983 inline void reverse()
998 inline static const T* ptrAt(
void const* ptr, ptrdiff_t count)
1000 return (
const T*)(
void const*)(((
char const*)ptr) + count * (ptrdiff_t)D.itemSize);
1012 inline static T* ptrAt(
void* ptr, ptrdiff_t count)
1014 return (T*)(
void*)(((
char*)ptr) + count * (ptrdiff_t)D.itemSize);