3 #ifndef INCLUDE_NN_NLIB_NLIST_H_
4 #define INCLUDE_NN_NLIB_NLIST_H_
13 #include "nn/nlib/Swap.h"
18 template <
class T,
class AL>
36 return 8 * ((1 << level) - 1);
39 return 8 * (1 << level);
42 bool ConfirmBack() const NLIB_NOEXCEPT;
43 void ClearSimple() NLIB_NOEXCEPT {
46 m_CurBlk = m_FirstBlk;
51 mutable Blk* m_CurBlk;
52 mutable size_t m_CurLevel;
53 mutable size_t m_CurIdx;
54 mutable Blk* m_FirstBlk;
61 class NlistConstIterator;
66 class NlistBaseT :
public NlistBase {
69 typedef const T& const_reference;
70 typedef NlistIterator<T> iterator;
71 typedef NlistConstIterator<T> const_iterator;
72 typedef size_t size_type;
75 typedef const T* const_pointer;
76 typedef ptrdiff_t difference_type;
81 return reinterpret_cast<T*
>(blk->item);
84 return reinterpret_cast<const T*
>(blk->item);
88 const Blk* p = this->AtSub(n, &base);
89 return p ?
const_cast<T*
>(&(GetItem(p)[n - base])) : NULL;
91 iterator Begin()
NLIB_NOEXCEPT {
return iterator(
this, TrueType()); }
92 iterator End()
NLIB_NOEXCEPT {
return iterator(
this, FalseType()); }
94 return const_iterator(
this, TrueType());
97 return const_iterator(
this, FalseType());
102 friend class NlistConstIterator<T>;
103 friend class NlistIterator<T>;
107 class NlistConstIterator
108 :
public std::iterator<std::forward_iterator_tag, T> {
110 typedef NlistBaseT<T> ContainerType;
111 typedef typename ContainerType::Blk Blk;
114 typedef typename std::iterator<std::forward_iterator_tag, T> BaseType;
115 typedef typename BaseType::iterator_category iterator_category;
116 typedef typename BaseType::value_type value_type;
117 typedef typename BaseType::difference_type difference_type;
118 typedef typename BaseType::pointer pointer;
119 typedef typename BaseType::reference reference;
128 NlistConstIterator(
const ContainerType* p, TrueType)
NLIB_NOEXCEPT {
129 ContainerType* rhs =
const_cast<ContainerType*
>(p);
131 m_Blk = rhs->m_FirstBlk;
132 m_ElemPtr = GetItem(m_Blk);
133 m_BlkEnd = m_ElemPtr + 8;
135 NlistConstIterator(
const ContainerType* p, FalseType)
NLIB_NOEXCEPT {
136 ContainerType* rhs =
const_cast<ContainerType*
>(p);
137 m_Idx = rhs->BlkBaseIdx(rhs->m_CurLevel) + rhs->m_CurIdx;
138 m_Blk = rhs->m_CurBlk;
139 m_ElemPtr = &(GetItem(m_Blk)[rhs->m_CurIdx]);
140 m_BlkEnd = GetItem(m_Blk) + rhs->BlkSize(rhs->m_CurLevel);
141 if (m_ElemPtr == m_BlkEnd) this->Normalize();
145 const T&
operator*() const NLIB_NOEXCEPT {
return *m_ElemPtr; }
146 const T* operator->() const NLIB_NOEXCEPT {
return m_ElemPtr; }
147 NlistConstIterator& operator++() NLIB_NOEXCEPT {
148 NLIB_ASSERT(m_ElemPtr != m_BlkEnd);
150 if (++m_ElemPtr == m_BlkEnd) this->Normalize();
153 NlistConstIterator operator++(
int) NLIB_NOEXCEPT {
154 NlistConstIterator rval(*
this);
158 bool operator==(
const NlistConstIterator& rhs)
const NLIB_NOEXCEPT {
159 return m_Idx == rhs.m_Idx && m_ElemPtr == rhs.m_ElemPtr;
161 bool operator!=(
const NlistConstIterator& rhs)
const NLIB_NOEXCEPT {
165 difference_type Distance(NlistConstIterator to)
const NLIB_NOEXCEPT {
166 return to.m_Idx - m_Idx;
170 static T* GetItem(Blk* blk) NLIB_NOEXCEPT {
171 return reinterpret_cast<T*
>(blk->item);
173 static const T* GetItem(
const Blk* blk) NLIB_NOEXCEPT {
174 return reinterpret_cast<const T*
>(blk->item);
176 bool Normalize() NLIB_NOEXCEPT;
183 friend class NlistBaseT<T>;
187 bool NlistConstIterator<T>::Normalize() NLIB_NOEXCEPT {
188 if (m_Blk && m_Blk->next) {
189 Blk* next = m_Blk->next;
190 size_t next_size = 2 *
static_cast<size_t>(m_BlkEnd - GetItem(m_Blk));
191 T* next_elemptr = GetItem(next);
192 T* next_end = next_elemptr + next_size;
194 m_ElemPtr = next_elemptr;
202 void NlistConstIterator<T>::Advance(difference_type n) NLIB_NOEXCEPT {
203 while (m_ElemPtr + n >= m_BlkEnd) {
204 n -= m_BlkEnd - m_ElemPtr;
205 m_Idx += m_BlkEnd - m_ElemPtr;
206 m_ElemPtr = m_BlkEnd;
207 if (!this->Normalize())
return;
214 class NlistIterator :
public NlistConstIterator<T> {
216 typedef NlistBaseT<T> ContainerType;
217 typedef typename ContainerType::Blk Blk;
218 typedef NlistConstIterator<T> MyBase;
221 typedef typename NlistConstIterator<T>::BaseType BaseType;
222 typedef typename BaseType::iterator_category iterator_category;
223 typedef typename BaseType::value_type value_type;
224 typedef typename BaseType::difference_type difference_type;
225 typedef typename BaseType::pointer pointer;
226 typedef typename BaseType::reference reference;
229 NLIB_CEXPR NlistIterator() NLIB_NOEXCEPT : MyBase() {}
232 NlistIterator(
const ContainerType* p, TrueType) NLIB_NOEXCEPT : MyBase(p, TrueType()) {}
233 NlistIterator(
const ContainerType* p, FalseType) NLIB_NOEXCEPT : MyBase(p, FalseType()) {}
237 const MyBase* tmp =
static_cast<const MyBase*
>(
this);
238 return const_cast<T&
>(**tmp);
240 T* operator->() const NLIB_NOEXCEPT {
241 const MyBase* tmp =
static_cast<const MyBase*
>(
this);
242 return const_cast<T*
>(tmp->operator->());
244 NlistIterator& operator++() NLIB_NOEXCEPT {
245 MyBase* tmp =
static_cast<MyBase*
>(
this);
249 NlistIterator operator++(
int) NLIB_NOEXCEPT {
250 NlistIterator rval(*
this);
254 bool operator==(
const NlistIterator& rhs)
const NLIB_NOEXCEPT {
255 const MyBase* tmp =
static_cast<const MyBase*
>(
this);
256 const MyBase* tmp2 =
static_cast<const MyBase*
>(&rhs);
257 return *tmp == *tmp2;
259 bool operator!=(
const NlistIterator& rhs)
const NLIB_NOEXCEPT {
262 difference_type Distance(NlistIterator to)
const NLIB_NOEXCEPT {
263 const MyBase* tmp =
static_cast<const MyBase*
>(
this);
264 const MyBase* tmp2 =
static_cast<const MyBase*
>(&to);
265 return tmp->Distance(*tmp2);
269 friend class NlistBaseT<T>;
272 template<
bool is_empty,
class AL>
275 NlistAlloc() NLIB_NOEXCEPT : m_Alloc(AL()) {}
276 explicit NlistAlloc(
const AL& al) NLIB_NOEXCEPT : m_Alloc(al) {}
279 AL& _GetNlistAlloc() const NLIB_NOEXCEPT {
280 return const_cast<AL&
>(m_Alloc);
282 void _SwapNlistAlloc(NlistAlloc& rhs) NLIB_NOEXCEPT {
284 swap(m_Alloc, rhs.m_Alloc);
292 class NlistAlloc <true, AL> {
294 NlistAlloc() NLIB_NOEXCEPT {}
295 explicit NlistAlloc(
const AL& al) NLIB_NOEXCEPT { NLIB_UNUSED(al); }
298 AL _GetNlistAlloc() const NLIB_NOEXCEPT {
return AL(); }
299 void _SwapNlistAlloc(NlistAlloc& rhs) NLIB_NOEXCEPT {
306 template <
class T,
class AL = std::allocator<
char> >
307 class Nlist :
public nlist::NlistBaseT<T>,
308 public nlist::NlistAlloc<IsEmpty<AL>::value, AL> {
333 typedef typename nlist::NlistBaseT<T> BaseType;
334 typedef typename nlist::NlistAlloc<IsEmpty<AL>::value, AL> AllocType;
335 using BaseType::m_CurBlk;
336 using BaseType::m_CurIdx;
337 using BaseType::m_CurLevel;
338 using BaseType::m_FirstBlk;
339 using BaseType::ConfirmBack;
340 using BaseType::ClearSimple;
341 using BaseType::BlkBaseIdx;
342 using BaseType::BlkSize;
343 using BaseType::GetItem;
344 using BaseType::Begin;
346 typedef typename BaseType::Blk Blk;
361 Nlist() NLIB_NOEXCEPT : AllocType(AL()) {}
362 explicit Nlist(
const AL& al) NLIB_NOEXCEPT : AllocType(al) {}
363 ~
Nlist() NLIB_NOEXCEPT;
364 NLIB_MOVE_MEMBER_HELPER_2(
Nlist, BaseType, AllocType)
365 size_type size() const NLIB_NOEXCEPT {
366 return BlkBaseIdx(m_CurLevel) + m_CurIdx;
370 return (NULL != this->LastBlock(&lv)) ? BlkBaseIdx(lv + 1) : 0;
372 bool empty() const NLIB_NOEXCEPT {
return m_CurLevel == 0 && m_CurIdx == 0; }
374 return Resize(n,
typename IsTriviallyDefaultConstructible<T>::type());
378 void* p = this->PushBack();
380 pointer ptr = MyCtor(p,
typename IsTriviallyDefaultConstructible<T>::type());
384 #ifdef NLIB_CXX11_RVALUE_REFERENCES
385 pointer push_back(T&& rhs) NLIB_NOEXCEPT {
386 #if defined(NLIB_HAS_NATIVE_TYPETRAITS) && !defined(NLIB_HAS_TR1_TYPETRAITS)
389 void* p = this->PushBack();
391 pointer ptr =
new (p) T(std::forward<T>(rhs));
396 pointer push_back(
const T& rhs) {
397 void* p = this->PushBack();
399 pointer ptr =
new (p) T(rhs);
404 return this->pop_back_(
typename IsTriviallyDestructible<T>::type());
409 swap(m_CurBlk, rhs.m_CurBlk);
410 swap(m_CurLevel, rhs.m_CurLevel);
411 swap(m_CurIdx, rhs.m_CurIdx);
412 swap(m_FirstBlk, rhs.m_FirstBlk);
413 AllocType::_SwapNlistAlloc(rhs);
416 Clear(
typename IsTriviallyDestructible<T>::type());
419 return AllocType::_GetNlistAlloc();
423 if (m_CurIdx == 0) ConfirmBack();
424 return GetItem(m_CurBlk)[m_CurIdx - 1];
427 if (m_CurIdx == 0) ConfirmBack();
428 return GetItem(m_CurBlk)[m_CurIdx - 1];
430 const_reference
front()
const {
return GetItem(m_FirstBlk)[0]; }
431 reference
front() {
return GetItem(m_FirstBlk)[0]; }
433 NLIB_ASSERT(idx < this->size());
434 return *this->At(idx);
437 NLIB_ASSERT(idx < this->size());
438 return *this->At(idx);
442 if (!m_FirstBlk && !ConfirmFirstBlk())
return iterator();
445 const_iterator
begin() const NLIB_NOEXCEPT {
446 if (!m_FirstBlk && !ConfirmFirstBlk())
return const_iterator();
449 const_iterator
cbegin() const NLIB_NOEXCEPT {
450 if (!m_FirstBlk && !ConfirmFirstBlk())
return const_iterator();
454 iterator
end() NLIB_NOEXCEPT {
455 if (!m_FirstBlk && !ConfirmFirstBlk())
return iterator();
458 const_iterator
end() const NLIB_NOEXCEPT {
459 if (!m_FirstBlk && !ConfirmFirstBlk())
return const_iterator();
462 const_iterator
cend() const NLIB_NOEXCEPT {
463 if (!m_FirstBlk && !ConfirmFirstBlk())
return const_iterator();
468 if (!m_CurBlk)
return;
469 Blk* p = m_CurBlk->next;
470 m_CurBlk->next = NULL;
471 DeallocBlkList(p, static_cast<int>(m_CurLevel + 1));
473 #if defined(NLIB_CXX11_RVALUE_REFERENCES) && defined(NLIB_CXX11_VARIADIC_TEMPLATES)
474 template<
class... Args>
475 pointer EmplaceBack(Args&&... args) {
476 void* p = this->PushBack();
478 pointer ptr =
new (p) T(std::forward<Args>(args)...);
485 void* p = this->PushBack();
487 pointer ptr =
new (p) T(
const_cast<typename RemoveConst<A1>::type&
>(a1));
491 template <
class A1,
class A2>
493 void* p = this->PushBack();
495 pointer ptr =
new (p) T(
const_cast<typename RemoveConst<A1>::type&
>(a1),
496 const_cast<typename RemoveConst<A2>::type&
>(a2));
500 template <
class A1,
class A2,
class A3>
502 void* p = this->PushBack();
504 pointer ptr =
new (p) T(
const_cast<typename RemoveConst<A1>::type&
>(a1),
505 const_cast<typename RemoveConst<A2>::type&
>(a2),
506 const_cast<typename RemoveConst<A3>::type&
>(a3));
510 template <
class A1,
class A2,
class A3,
class A4>
511 pointer
EmplaceBack(
const A1& a1,
const A2& a2,
const A3& a3,
const A4& a4) {
512 void* p = this->PushBack();
514 pointer ptr =
new (p) T(
const_cast<typename RemoveConst<A1>::type&
>(a1),
515 const_cast<typename RemoveConst<A2>::type&
>(a2),
516 const_cast<typename RemoveConst<A3>::type&
>(a3),
517 const_cast<typename RemoveConst<A4>::type&
>(a4));
521 template <
class A1,
class A2,
class A3,
class A4,
class A5>
523 EmplaceBack(
const A1& a1,
const A2& a2,
const A3& a3,
const A4& a4,
const A5& a5) {
524 void* p = this->PushBack();
526 pointer ptr =
new (p) T(
const_cast<typename RemoveConst<A1>::type&
>(a1),
527 const_cast<typename RemoveConst<A2>::type&
>(a2),
528 const_cast<typename RemoveConst<A3>::type&
>(a3),
529 const_cast<typename RemoveConst<A4>::type&
>(a4),
530 const_cast<typename RemoveConst<A5>::type&
>(a5));
546 void DestroyBlk(Blk*,
size_t, TrueType) const NLIB_NOEXCEPT {}
547 void DestroyBlk(Blk* p,
size_t n, FalseType) const NLIB_NOEXCEPT;
548 void DestroyBlk(Blk* p,
size_t n) const NLIB_NOEXCEPT {
549 DestroyBlk(p, n,
typename IsTriviallyDestructible<T>::type());
551 bool ConfirmFirstBlk() const NLIB_NOEXCEPT;
552 void* PushBack() NLIB_NOEXCEPT;
553 void Clear(FalseType) NLIB_NOEXCEPT;
554 void Clear(TrueType) NLIB_NOEXCEPT { ClearSimple(); }
555 bool Resize(
size_t n, FalseType) NLIB_NOEXCEPT;
556 bool Resize(
size_t n, TrueType) NLIB_NOEXCEPT;
557 T* MyCtor(
void* p, TrueType) NLIB_NOEXCEPT {
558 return reinterpret_cast<T*
>(p);
560 T* MyCtor(
void* p, FalseType) {
564 bool pop_back_(FalseType) NLIB_NOEXCEPT {
566 if (!ConfirmBack())
return false;
568 reference item = GetItem(m_CurBlk)[--m_CurIdx];
573 bool pop_back_(TrueType) NLIB_NOEXCEPT {
575 if (!ConfirmBack())
return false;
585 template <
class T,
class AL>
588 this->DeallocBlkList(m_FirstBlk, 0);
593 template <
class T,
class AL>
594 class ResizeRewinder {
596 ResizeRewinder(
Nlist<T, AL>& l) NLIB_NOEXCEPT : m_Count(0), m_List(l) {}
597 void PushBack(
size_t n) {
598 for (; m_Count < n; ++m_Count) {
603 ~ResizeRewinder() NLIB_NOEXCEPT {
604 for (; m_Count > 0; --m_Count) {
611 Nlist<T, AL>& m_List;
617 template <
class T,
class AL>
618 bool Nlist<T, AL>::Resize(
size_t n, FalseType) NLIB_NOEXCEPT {
620 size_t sz = this->size();
621 if (n == sz)
return true;
623 for (
size_t i = sz; i > n; --i) {
627 if (!this->reserve(n))
return false;
628 nlist::ResizeRewinder<T, AL> rewinder(*
this);
629 rewinder.PushBack(n);
634 template <
class T,
class AL>
635 bool Nlist<T, AL>::Resize(
size_t n, TrueType) NLIB_NOEXCEPT {
636 size_type sz = this->size();
637 if (n == sz)
return true;
639 for (size_type i = sz; i > n; --i) {
643 if (!this->reserve(n))
return false;
647 size_t lower = this->BlkBaseIdx(m_CurLevel);
648 size_t upper = this->BlkBaseIdx(m_CurLevel + 1);
651 m_CurBlk = m_CurBlk->next;
653 upper = this->BlkBaseIdx(m_CurLevel + 1);
655 m_CurIdx =
static_cast<size_t>(n - lower);
660 template <
class T,
class AL>
662 if (n == 0 || n <= BlkBaseIdx(m_CurLevel + 1))
return true;
663 if (!m_FirstBlk && !this->ConfirmFirstBlk())
return false;
665 Blk* blk = this->LastBlock(&lv);
667 if (n <= BlkBaseIdx(lv + 1))
return true;
669 Blk* p = this->AllocBlk(BlkSize(lv));
670 if (!p)
return false;
676 template <
class T,
class AL>
681 size_t sz =
sizeof(Blk) + n *
sizeof(T);
684 pp = AllocType::_GetNlistAlloc().allocate(sz);
686 #ifdef NLIB_EXCEPTION_ENABLED
687 NLIB_CATCH(
const std::bad_alloc&) {
return NULL; }
689 if (!pp)
return NULL;
690 Blk* p =
reinterpret_cast<Blk*
>(pp);
692 p->item =
reinterpret_cast<T*
>(p + 1);
696 template <
class T,
class AL>
697 void Nlist<T, AL>::DeallocBlkList(Blk* p,
int lv)
const NLIB_NOEXCEPT {
699 size_t n = BlkSize(lv);
704 AllocType::_GetNlistAlloc().deallocate(reinterpret_cast<char*>(pp),
705 sizeof(Blk) + n *
sizeof(T));
710 template <
class T,
class AL>
711 void Nlist<T, AL>::DestroyBlk(Blk* p,
size_t n, FalseType) const NLIB_NOEXCEPT {
715 T* base =
reinterpret_cast<T*
>(p->item);
717 for (
size_t i = 0; i < n; ++i) {
722 template <
class T,
class AL>
723 bool Nlist<T, AL>::ConfirmFirstBlk() const NLIB_NOEXCEPT {
724 Blk* p = AllocBlk(BlkSize(0));
725 if (!p)
return false;
733 template <
class T,
class AL>
734 void* Nlist<T, AL>::PushBack() NLIB_NOEXCEPT {
735 if (!m_FirstBlk && !ConfirmFirstBlk())
return NULL;
736 if (m_CurIdx == BlkSize(m_CurLevel)) {
737 if (!m_CurBlk->next) {
738 Blk* p = AllocBlk(BlkSize(m_CurLevel + 1));
743 m_CurBlk = m_CurBlk->next;
750 T& item = GetItem(m_CurBlk)[m_CurIdx];
754 template <
class T,
class AL>
755 void Nlist<T, AL>::Clear(FalseType) NLIB_NOEXCEPT {
759 while (p != m_CurBlk) {
760 size_t cnt = BlkSize(lv);
766 DestroyBlk(p, m_CurIdx);
771 template <
class T,
class AL1,
class AL2>
774 return lhs.size() == rhs.size() && std::equal(lhs.begin(), lhs.end(), rhs.begin());
777 template <
class T,
class AL1,
class AL2>
780 return !(lhs == rhs);
783 template <
class T,
class AL1,
class AL2>
784 inline bool operator<(const Nlist<T, AL1>& lhs,
786 return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
789 template <
class T,
class AL1,
class AL2>
795 template <
class T,
class AL1,
class AL2>
796 inline bool operator<=(const Nlist<T, AL1>& lhs,
798 return (!(rhs < lhs));
801 template <
class T,
class AL1,
class AL2>
804 return (!(lhs < rhs));
807 template <
class AL = std::allocator<
char> >
809 typedef Nlist<char*, AL> ContainerType;
812 typedef AL allocator_type;
813 typedef typename ContainerType::iterator iterator;
814 typedef typename ContainerType::const_iterator const_iterator;
817 StringList() NLIB_NOEXCEPT : m_List() {}
818 explicit StringList(
const AL& al) : m_List(al) {}
819 ~StringList() NLIB_NOEXCEPT;
820 size_t size() const NLIB_NOEXCEPT {
return m_List.size(); }
821 size_t capacity() const NLIB_NOEXCEPT {
return m_List.capacity(); }
822 bool empty() const NLIB_NOEXCEPT {
return m_List.empty(); }
823 bool reserve(
size_t n) {
return m_List.reserve(n); }
824 bool resize(
size_t n) {
return m_List.resize(n); }
826 char** push_back(
const char* str);
827 template <
class Iterator>
828 char** push_back(Iterator first, Iterator last);
830 bool pop_back() NLIB_NOEXCEPT;
831 void swap(StringList& rhs) NLIB_NOEXCEPT { m_List.swap(rhs.m_List); }
832 void clear() NLIB_NOEXCEPT { m_List.clear(); }
833 allocator_type get_allocator()
const {
return m_List.get_allocator(); }
835 const char* back()
const {
return m_List.back(); }
836 char* back() {
return m_List.back(); }
837 const char* front()
const {
return m_List.front(); }
838 char* front() {
return m_List.front(); }
839 const char* operator[](
size_t idx)
const {
return m_List[idx]; }
840 char* operator[](
size_t idx) {
return m_List[idx]; }
841 iterator begin() NLIB_NOEXCEPT {
return m_List.begin(); }
842 const_iterator begin() const NLIB_NOEXCEPT {
return m_List.begin(); }
843 const_iterator cbegin() NLIB_NOEXCEPT {
return m_List.cbegin(); }
845 iterator end() NLIB_NOEXCEPT {
return m_List.end(); }
846 const_iterator end() const NLIB_NOEXCEPT {
return m_List.end(); }
847 const_iterator cend() NLIB_NOEXCEPT {
return m_List.cend(); }
849 void shrink_to_fit() { m_List.shrink_to_fit(); }
850 void Clobber() NLIB_NOEXCEPT { m_List.clobber(); }
852 char** Replace(iterator it,
const char* str);
853 char** Replace(
size_t idx,
const char* str) {
854 if (idx >= m_List.size())
return NULL;
855 iterator it = m_List.begin();
857 return this->Replace(it, str);
861 void Dealloc(
const char* ptr)
const {
864 this->get_allocator().deallocate(const_cast<char*>(ptr), 0);
867 char* StrDup(
const char* ptr)
const;
868 char* Alloc(
size_t nBytes)
const {
869 return this->get_allocator().allocate(nBytes);
873 ContainerType m_List;
878 char* StringList<AL>::StrDup(
const char* ptr)
const {
880 void* p = this->Alloc(nBytes);
883 return reinterpret_cast<char*
>(p);
887 StringList<AL>::~StringList() NLIB_NOEXCEPT {
888 const_iterator it = this->cbegin();
889 const_iterator it_end = this->cend();
890 while (it != it_end) {
897 char** StringList<AL>::push_back(
const char* str) {
900 dup = this->StrDup(str);
901 if (!dup)
return NULL;
905 char** ptrStr = m_List.push_back(dup);
906 if (!ptrStr) this->Dealloc(dup);
911 template <
class Iterator>
912 char** StringList<AL>::push_back(Iterator first, Iterator last) {
913 typename std::iterator_traits<Iterator>::difference_type n = std::distance(first, last);
914 char* str = this->Alloc(n + 1);
915 if (!str)
return NULL;
916 std::copy(first, last, str);
918 char** rval = m_List.push_back(str);
919 if (!rval) this->Dealloc(str);
924 bool StringList<AL>::pop_back() NLIB_NOEXCEPT {
925 if (m_List.empty())
return false;
926 Dealloc(m_List.back());
927 return m_List.pop_back();
931 char** StringList<AL>::Replace(iterator it,
const char* str) {
934 dup = this->StrDup(str);
935 if (!dup)
return NULL;
945 bool AppendString(Nlist<char, AL>* obj,
const char* str) {
947 if (!obj->reserve(obj->size() + n))
return false;
949 obj->push_back(*str);
959 template <
class T,
class Distance>
960 inline void advance(::nlib_ns::nlist::NlistIterator<T>& pos,
962 pos.Advance(static_cast<size_t>(n));
966 inline std::ptrdiff_t distance(const ::nlib_ns::nlist::NlistIterator<T>& first,
967 const ::nlib_ns::nlist::NlistIterator<T>& last) {
968 return first.Distance(last);
973 #ifndef NLIB_STD_SWAP_WORKAROUND
976 NLIB_DEFINE_STD_SWAP_T_BEGIN1(
std)
979 NLIB_DEFINE_STD_SWAP_T2(T, AL, NLIB_NS::Nlist)
980 NLIB_DEFINE_STD_SWAP_T1(AL, NLIB_NS::StringList)
982 #ifndef NLIB_STD_SWAP_WORKAROUND
985 NLIB_DEFINE_STD_SWAP_T_END1(
std)
988 #endif // INCLUDE_NN_NLIB_NLIST_H_
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
Nlist(const AL &al) noexcept
アロケータを指定します。空のコンテナを作成します。
void swap(Nlist &rhs) noexcept
コンテナをスワップします。
BaseType::const_pointer const_pointer
const T*
reference back()
末尾の要素の参照を返します。
BaseType::pointer pointer
T*.
C++11の標準ヘッダとなるtype_traitsの代用定義です。 コンパイラや標準ライブラリによってサポートされてい...
Nlist() noexcept
デフォルトコンストラクタです。空のコンテナを作成します。
const_iterator begin() const noexcept
コンテナの先頭を指す反復子を返します。
BaseType::reference reference
T&.
#define NLIB_CATCH(x)
例外が有効なときはcatch(x), そうでなければif (true)が定義されます。
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
bool operator>=(const Nlist< T, AL1 > &lhs, const Nlist< T, AL2 > &rhs) noexcept
2つのリストを辞書順で比較します。
const_reference front() const
front()と同様です。
pointer EmplaceBack(const A1 &a1, const A2 &a2, const A3 &a3)
インプレイスで要素を追加します。
BaseType::size_type size_type
符号なし整数型(size_t)
bool operator>(const Nlist< T, AL1 > &lhs, const Nlist< T, AL2 > &rhs) noexcept
2つのリストを辞書順で比較します。
iterator begin() noexcept
コンテナの先頭を指す反復子を返します。
void shrink_to_fit() noexcept
可能ならばアロケートされたメモリを返却します。
#define NLIB_TRY
例外が有効なときはtry, そうでなければif (true)が定義されます。
bool operator==(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価ならば、trueを返します。
bool operator!=(const HeapHash &rhs, const HeapHash &lhs)
2つのサマリを比較して等価でなければ、trueを返します。
const_reference back() const
back()と同様です。
const_iterator cend() const noexcept
コンテナの末尾を指す反復子を返します。
size_type capacity() const noexcept
アロケート済みの要素の個数を返します。
bool empty() const noexcept
コンテナが空かどうかを調べます。
BaseType::const_iterator const_iterator
読み取り専用フォワードイテレータ
bool resize(size_type n) noexcept
コンテナをリサイズします。
pointer push_back()
末尾に要素を追加してデフォルトコンストラクタで初期化します。
const_reference operator[](size_type idx) const
operator[](size_t idx) と同様です。
reference operator[](size_type idx)
インデックスで要素を参照します。
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
pointer EmplaceBack(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
インプレイスで要素を追加します。
const_iterator end() const noexcept
コンテナの末尾を指す反復子を返します。
void clear() noexcept
コンテナをクリアします。
const_iterator cbegin() const noexcept
コンテナの先頭を指す反復子を返します。
reference front()
先頭の要素の参照を返します。
BaseType::iterator iterator
フォワードイテレータ
BaseType::difference_type difference_type
符号つき整数型(ptrdiff_t)
BaseType::value_type value_type
要素型 T
TimeSpan operator*(int i, const TimeSpan &rhs) noexcept
rhs を i 倍します。
pointer EmplaceBack(const A1 &a1)
インプレイスで要素を追加します。
void Clobber() noexcept
要素のデストラクタを呼んだりコンテナのメモリを解放することなく、コンテナを空に戻す。 ...
std::vectorに似た、コピーコンストラクタを持たないオブジェクトを格納可能なコンテナ類似クラスです。 ...
#define NLIB_STATIC_ASSERT(exp)
静的アサートが定義されます。利用可能であればstatic_assertを利用します。
#define NLIB_ALIGNOF(tp)
alignof(tp)又は同等の定義がされます。
pointer EmplaceBack(const A1 &a1, const A2 &a2)
インプレイスで要素を追加します。
pointer EmplaceBack(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5)
インプレイスで要素を追加します。
AL allocator_type
アロケータの型 AL
BaseType::reference const_reference
const T&
iterator end() noexcept
コンテナの末尾を指す反復子を返します。
bool pop_back() noexcept
末尾の要素を削除します。
allocator_type get_allocator() const noexcept
アロケータを取得します。