nlib
Nqueue.h
[詳解]
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_NQUEUE_H_
17 #define INCLUDE_NN_NLIB_NQUEUE_H_
18 
19 #include <memory>
20 #include <utility>
21 #include "nn/nlib/Swap.h"
22 #include "nn/nlib/Nlist.h"
23 #include "nn/nlib/TypeTraits.h"
24 
25 NLIB_NAMESPACE_BEGIN
26 
27 extern void* nqueue_enabler;
28 
29 template <class T, class AL = std::allocator<char> >
31  public:
32  NLIB_CEXPR Nqueue() NLIB_NOEXCEPT : beg1_(0), end1_(0), beg2_(0), end2_(0) {}
34 #ifdef __cpp_rvalue_references
36  : beg1_(rhs.beg1_), end1_(rhs.end1_), beg2_(rhs.beg2_), end2_(rhs.end2_),
37  list_(std::move(rhs.list_)) {
38  beg1_ = end1_ = beg2_ = end2_ = 0;
39  }
41  beg1_ = rhs.beg1_;
42  end1_ = rhs.end1_;
43  beg2_ = rhs.beg2_;
44  end2_ = rhs.end2_;
45  list_ = std::move(rhs.list_);
46  beg1_ = end1_ = beg2_ = end2_ = 0;
47  return *this;
48  }
49 #endif
51  : beg1_(rhs.beg1_), end1_(rhs.end1_), beg2_(rhs.beg2_), end2_(rhs.end2_),
52  list_(rhs.list_, move_tag()) {
53  beg1_ = end1_ = beg2_ = end2_ = 0;
54  }
56  beg1_ = rhs.beg1_;
57  end1_ = rhs.end1_;
58  beg2_ = rhs.beg2_;
59  end2_ = rhs.end2_;
60  list_.assign(rhs.list_, move_tag());
61  beg1_ = end1_ = beg2_ = end2_ = 0;
62  return *this;
63  }
64  size_t size() const NLIB_NOEXCEPT { return (end1_ - beg1_) + (end2_ - beg2_); }
65  size_t capacity() const NLIB_NOEXCEPT { return list_.capacity(); }
66  bool empty() const NLIB_NOEXCEPT { return end1_ - beg1_ == 0 && end2_ - beg2_ == 0; }
67  T* push_back() NLIB_NOEXCEPT;
68 #ifdef __cpp_rvalue_references
69  T* push_back(T&& rhs) NLIB_NOEXCEPT;
70 #endif
71  bool pop_front() NLIB_NOEXCEPT {
72  T tmp;
73  return this->pop_front_swap(&tmp);
74  }
75  bool push_back_swap(T* v) NLIB_NOEXCEPT {
76  T* tmp = this->push_back();
77  if (!tmp || !v) return false;
78  using std::swap;
79  swap(*tmp, *v);
80  return true;
81  }
82  bool pop_front_swap(T* v) NLIB_NOEXCEPT;
83  NLIB_DEPRECATED void swap(Nqueue& rhs) NLIB_NOEXCEPT { // NOLINT
84  using std::swap;
85  swap(beg1_, rhs.beg1_);
86  swap(end1_, rhs.end1_);
87  swap(beg2_, rhs.beg2_);
88  swap(end2_, rhs.end2_);
89  swap(list_, rhs.list_);
90  }
91 
92  private:
93  uint32_t beg1_;
94  uint32_t end1_;
95  uint32_t beg2_;
96  uint32_t end2_;
97  Nlist<T, AL> list_;
99 };
100 
101 template <class T, class AL>
103  if (end1_ != beg2_ && beg2_ != end2_) {
104  using std::swap;
105  swap(list_[end1_++], list_[beg2_++]);
106  if (beg2_ != end2_) {
107  swap(list_[end1_++], list_[beg2_++]);
108  }
109  if (beg2_ == end2_) {
110  beg2_ = beg1_;
111  end2_ = end1_;
112  beg1_ = end1_ = 0;
113  }
114  }
115  if (list_.size() == end2_) {
116  T* tmp = list_.push_back();
117  if (tmp) ++end2_;
118  return tmp;
119  } else {
120  return &list_[end2_++];
121  }
122 }
123 
124 #ifdef __cpp_rvalue_references
125 template <class T, class AL>
127  if (end1_ != beg2_ && beg2_ != end2_) {
128  using std::swap;
129  swap(list_[end1_++], list_[beg2_++]);
130  if (beg2_ != end2_) {
131  swap(list_[end1_++], list_[beg2_++]);
132  }
133  if (beg2_ == end2_) {
134  beg2_ = beg1_;
135  end2_ = end1_;
136  beg1_ = end1_ = 0;
137  }
138  }
139  if (list_.size() == end2_) {
140 #ifdef NLIB_HAS_NATIVE_TYPETRAITS
141  NLIB_STATIC_ASSERT(std::is_nothrow_move_constructible<T>::value);
142 #endif
143  T* tmp = list_.push_back(std::move(rhs));
144  if (tmp) ++end2_;
145  return tmp;
146  } else {
147 #ifdef NLIB_HAS_NATIVE_TYPETRAITS
148  NLIB_STATIC_ASSERT(std::is_nothrow_move_assignable<T>::value);
149 #endif
150  list_[end2_] = std::move(rhs);
151  return &list_[end2_++];
152  }
153 }
154 #endif
155 
156 template <class T, class AL>
158  if (!v) return false;
159  using std::swap;
160  if (beg1_ != end1_) {
161  swap(*v, list_[beg1_++]);
162  if (beg1_ == end1_) {
163  beg1_ = end1_ = 0;
164  } else if ((end1_ - beg1_) * 8 < end1_) {
165  uint32_t cnt = static_cast<uint32_t>(end1_ - beg1_);
166  for (uint32_t i = 0; i < cnt; ++i) {
167  swap(list_[i], list_[beg1_ + i]);
168  }
169  beg1_ = 0;
170  end1_ = cnt;
171  }
172  } else if (beg2_ != end2_) {
173  NLIB_ASSERT(beg1_ + end1_ == 0);
174  swap(*v, list_[beg2_++]);
175  if (beg2_ == end2_) beg2_ = end2_ = 0;
176  } else {
177  return false;
178  }
179  return true;
180 }
181 
182 NLIB_NAMESPACE_END
183 
184 NLIB_DEFINE_STD_SWAP_T_BEGIN2(nn, nlib) // NOLINT
185 NLIB_DEFINE_STD_SWAP_T2(T, AL, NLIB_NS::Nqueue) // NOLINT
186 NLIB_DEFINE_STD_SWAP_T_END2(nn, nlib) // NOLINT
187 
188 #endif // INCLUDE_NN_NLIB_NQUEUE_H_
~Nqueue() noexcept
デストラクタです。
Definition: Nqueue.h:33
bool push_back_swap(T *v) noexcept
キューに要素を追加してから、その要素とvをstd::swapによって交換します。
Definition: Nqueue.h:75
C++11の標準ヘッダとなるtype_traitsの代用定義です。 コンパイラや標準ライブラリによってサポートされてい...
#define NLIB_DISALLOW_COPY_AND_ASSIGN(TypeName)
TypeName で指定されたクラスのコピーコンストラクタと代入演算子を禁止します。
Definition: Config.h:179
Definition: Base64.h:25
std::queueに似た、コピーコンストラクタを持たないオブジェクトを格納可能なコンテナ類似クラスです。 ...
Definition: Nqueue.h:30
Nqueue & assign(Nqueue &rhs, move_tag) noexcept
ムーブ代入演算子に相当します。
Definition: Nqueue.h:55
constexpr Nqueue() noexcept
デフォルトコンストラクタです。空のキューを作成します。
Definition: Nqueue.h:32
Nqueue(Nqueue &&rhs) noexcept
ムーブコンストラクタです。C++11の利用時に有効です。
Definition: Nqueue.h:35
void swap(Nqueue &rhs) noexcept
コンテナをスワップします。
Definition: Nqueue.h:83
#define NLIB_DEPRECATED
関数等がdeprecatedになったことを示します。
Definition: Config.h:109
Nqueue(Nqueue &rhs, move_tag) noexcept
ムーブコンストラクタに相当します。
Definition: Nqueue.h:50
size_t size() const noexcept
格納されている要素の個数を返します。
Definition: Nqueue.h:64
std::vectorに似ていますが、コピーできないオブジェクトを格納可能なクラスが定義されています。 ...
空の構造体で、関数の引数をムーブすべきことを示すために利用されます。
Definition: Config.h:265
bool pop_front() noexcept
先頭の要素をキューから取り出します。
Definition: Nqueue.h:71
#define NLIB_NOEXCEPT
環境に合わせてnoexcept 又は同等の定義がされます。
Definition: Config.h:105
#define NLIB_CEXPR
利用可能であればconstexprが定義されます。そうでない場合は空文字列です。
Definition: Config.h:107
std::vectorに似た、コピーコンストラクタを持たないオブジェクトを格納可能なコンテナ類似クラスです。 ...
Definition: Nlist.h:32
bool empty() const noexcept
コンテナが空かどうかを調べます。
Definition: Nqueue.h:66
#define NLIB_FINAL
利用可能であればfinalが定義されます。そうでない場合は空文字列です。
Definition: Config.h:245
#define NLIB_STATIC_ASSERT(exp)
静的アサートが定義されます。利用可能であればstatic_assertを利用します。
Definition: Config.h:170
size_t capacity() const noexcept
アロケート済みの要素の個数を返します。
Definition: Nqueue.h:65
Nqueue & operator=(Nqueue &&rhs) noexcept
ムーブ代入演算子です。C++11の利用時に有効です。
Definition: Nqueue.h:40