Theolizer  Version.1.2.0
serializer for C++ / Do you want to update your classes easily ?
rbfor.h
[詳解]
1 //############################################################################
2 /*!
3  @brief 範囲ベースfor拡張
4  @details ①RBForAdaptor:範囲ベースfor専用の便利ツール
5    コンテナやレンジを受け取り、指定の「レンジ」へ設定して保持する。<br>
6    begin(), end()はRangeReferencerを返却する<br>
7  ②RBForReferencer:範囲ベースfor専用のiterator(かなり特殊)<br>
8    RBForAdaptorへの参照のみを保持する<br>
9      operator*()は「レンジ」を返却<br>
10      operator++()はRBForAdaptorのdrop_front()を呼ぶ<br>
11      operator!=()はRBForAdaptorのempty()を呼ぶ<br>
12  ※特記事項<br>
13    RBForAdaptor::end()が返却したインスタンスのメンバ関数は呼び出し禁止。<br>
14  ※注意事項:名前空間internalのアイテムは直接使わないこと<br>
15  @ingroup TheolizerLib
16  @file rbfor.h
17  @author Yoshinori Tahara
18  @date 2017/07/14 Created
19 */
20 /*
21  © 2016 Theoride Technology (http://theolizer.com/) All Rights Reserved.
22  "Theolizer" is a registered trademark of Theoride Technology.
23 
24  "Theolizer" License
25  In the case where you are in possession of a valid “Theolizer” License,
26  you may use this file in accordance with the terms and conditions of
27  the use license determined by Theoride Technology.
28 
29  General Public License Version 3 ("GPLv3")
30  You may use this file in accordance with the terms and conditions of
31  GPLv3 published by Free Software Foundation.
32  Please confirm the contents of GPLv3 at https://www.gnu.org/licenses/gpl.txt .
33  A copy of GPLv3 is also saved in a LICENSE.TXT file.
34 
35  商用ライセンス
36  あなたが有効なTheolizer商用ライセンスを保持している場合、
37  セオライド テクノロジーの定める使用許諾書の条件に従って、
38  このファイルを取り扱うことができます。
39 
40  General Public License Version 3(以下GPLv3)
41  Free Software Foundationが公表するGPLv3の使用条件に従って、
42  あなたはこのファイルを取り扱うことができます。
43  GPLv3の内容を https://www.gnu.org/licenses/gpl.txt にて確認して下さい。
44  またGPLv3のコピーをLICENSE.TXTファイルにおいてます。
45 */
46 //############################################################################
47 
48 #if !defined(THEOLIZER_INTERNAL_RBFOR_H)
49 #define THEOLIZER_INTERNAL_RBFOR_H
50 
51 #include <stdexcept>
52 #include <utility>
53 
54 //############################################################################
55 // Begin
56 //############################################################################
57 
58 // ***************************************************************************
59 // 警告抑止
60 // ***************************************************************************
61 
62 #ifdef _MSC_VER
63  #pragma warning(push)
64  #pragma warning(disable:4100)
65 #endif
66 
67 namespace theolizer
68 {
69 namespace internal
70 {
71 #ifndef THEOLIZER_INTERNAL_DOXYGEN
72 
73 //############################################################################
74 // 範囲ベースfor拡張(ループ分割とインデックス番号他)
75 //############################################################################
76 
77 // ***************************************************************************
78 // RBForReferencer
79 // ***************************************************************************
80 
81 template<class tRBForAdaptor>
82 class RBForReferencer
83 {
84  typedef typename tRBForAdaptor::Range Range;
85  tRBForAdaptor& mRBForAdaptor;
86 public:
87  RBForReferencer(tRBForAdaptor& iRBForAdaptor) : mRBForAdaptor(iRBForAdaptor)
88  { }
89  Range& operator*()
90  {
91  return mRBForAdaptor;
92  }
93  void operator++()
94  {
95  mRBForAdaptor.drop_front();
96  }
97  bool operator!=(RBForReferencer const& iRhs) const
98  {
99  return !mRBForAdaptor.empty();
100  }
101 };
102 
103 // ***************************************************************************
104 // RBForAdaptor
105 // ***************************************************************************
106 
107 template<class tRange, class tIterator, class tNextFunc>
108 class RBForAdaptor : private tRange
109 {
110  tNextFunc mNextFunc; // drop_front時に呼び出す関数
111 public:
112  // コンストラクタ
113  RBForAdaptor(tIterator&& iBegin, tIterator&& iEnd, tNextFunc const& iNextFunc) :
114  tRange(std::forward<tIterator>(iBegin), std::forward<tIterator>(iEnd)),
115  mNextFunc(iNextFunc)
116  { }
117 private:
118  // RBForReferencer I/F
119  template<class> friend class internal::RBForReferencer;
120  typedef tRange Range;
121  typedef internal::RBForReferencer<RBForAdaptor> RBForReferencer;
122  void drop_front()
123  {
124  mNextFunc(tRange::front());
125  tRange::drop_front();
126  }
127 public:
128  // レンジ取り出し
129  tRange& getRange() {return *this;}
130 
131  // 範囲ベースfor I/F(プログラマーは使用禁止)
132  RBForReferencer begin() {return RBForReferencer(*this);}
133  RBForReferencer end() {return RBForReferencer(*this);}
134 };
135 
136 // ***************************************************************************
137 // ユーティリティ
138 // ***************************************************************************
139 
140 // ---------------------------------------------------------------------------
141 // デフォルトのtNextFunc処理
142 // ---------------------------------------------------------------------------
143 
144 struct NopFunctor
145 {
146  void operator()(...) { }
147 };
148 
149 #endif // THEOLIZER_INTERNAL_DOXYGEN
150 } // namespace internal
151 
152 // ---------------------------------------------------------------------------
153 /*!
154 @brief 範囲ベースfor用のRageを管理する基底クラス
155 @details for(auto&& aLoop : getRBForIndexer(コンテナ))
156  とした時のaLoopの型の基底クラスである。
157 */
158 // ---------------------------------------------------------------------------
159 
160 template<class tIterator>
162 {
163  typedef typename
164  std::remove_reference<decltype(*(std::declval<tIterator>()))>::type ValueType;
165 
166  tIterator mBegin;
167  tIterator mEnd;
168 public:
169  //! @ingroup RbFor
170  //! コンストラクタ(範囲開始と終了を設定する)
171  BasicRange(tIterator&& iBegin, tIterator&& iEnd) :
172  mBegin(std::forward<tIterator>(iBegin)),
173  mEnd (std::forward<tIterator>(iEnd))
174  { }
175 
176  //! @ingroup RbFor
177  //! 1つ次へ進める
178  void drop_front()
179  {
180  if (empty())
181  {
182  throw std::out_of_range("BasicRange::drop_front()");
183  }
184  ++mBegin;
185  }
186 
187  //! @ingroup RbFor
188  //! 先頭要素を取り出す
189  ValueType& front() {return *mBegin;}
190 
191  //! @ingroup RbFor
192  //! 開始位置と終了位置が一致している時empty
193  bool empty() const {return mBegin == mEnd;}
194 
195  //! @ingroup RbFor
196  //! 開始位置取り出し(範囲ベースfor専用)
197  tIterator begin() const {return mBegin;}
198 
199  //! @ingroup RbFor
200  //! 終了位置取り出し(範囲ベースfor専用)
201  tIterator end() const {return mEnd;}
202 
203  //! @ingroup RbFor
204  //! ポイント先メンバ取り出し(イテレータ的I/F)
205  tIterator operator->() {return mBegin;}
206 
207  //! @ingroup RbFor
208  //! ポイント先取り出し(イテレータ的I/F)
209  ValueType& operator*() {return front();}
210 
211  //! @ingroup RbFor
212  //! 前置インクリメント(イテレータ的I/F)
214  {
215  drop_front();
216  return *this;
217  }
218 
219  //! @ingroup RbFor
220  //! 後置インクリメント(イテレータ的I/F)
222  {
223  BasicRange ret(*this);
224  drop_front();
225  return ret;
226  }
227 };
228 
229 // ---------------------------------------------------------------------------
230 // インデックス機能クラス
231 // ---------------------------------------------------------------------------
232 
233 namespace internal
234 {
235 #ifndef THEOLIZER_INTERNAL_DOXYGEN
236 
237 template<class tIterator>
238 class Indexer : public BasicRange<tIterator>
239 {
240  std::size_t mIndex;
241 public:
242  Indexer(tIterator&& iBegin, tIterator&& iEnd) :
244  (
245  std::forward<tIterator>(iBegin),
246  std::forward<tIterator>(iEnd)
247  ),
248  mIndex(0)
249  { }
250  void drop_front()
251  {
252  ++mIndex;
254  }
255  std::size_t getIndex() const {return mIndex;}
256 
257  //! @ingroup RbFor
258  //! 前置インクリメント(イテレータ的I/F)
259  Indexer& operator++()
260  {
261  drop_front();
262  return *this;
263  }
264 
265  //! @ingroup RbFor
266  //! 後置インクリメント(イテレータ的I/F)
267  Indexer operator++(int)
268  {
269  Indexer ret(*this);
270  drop_front();
271  return ret;
272  }
273 };
274 
275 // ---------------------------------------------------------------------------
276 // RBForAdaptor生成ヘルパ
277 // ---------------------------------------------------------------------------
278 
279 template
280 <
281  template<class tIterator> class tRange,
282  class tContainer,
283  class tNextFunc=internal::NopFunctor
284 >
285 class MakeRBForAdaptor
286 {
287  typedef decltype(std::begin(std::declval<tContainer>())) Iterator;
288  typedef typename std::remove_reference<tNextFunc>::type NextFunc;
289 public:
290  typedef RBForAdaptor<tRange<Iterator>, Iterator, NextFunc> Type;
291 };
292 
293 #endif // THEOLIZER_INTERNAL_DOXYGEN
294 } // namespace internal
295 
296 // ***************************************************************************
297 // API関数
298 // ***************************************************************************
299 
300 // ---------------------------------------------------------------------------
301 /*!
302  @brief 汎用の範囲ベースfor用レンジ生成
303 */
304 // ---------------------------------------------------------------------------
305 
306 template
307 <
308  template<class tIterator> class tRange,
309  class tContainer,
310  class tNextFunc=internal::NopFunctor
311 >
312 auto getRBForAdaptor(tContainer&& iContainer, tNextFunc&& iNextFunc=internal::NopFunctor()) ->
313  typename internal::MakeRBForAdaptor<tRange, tContainer, tNextFunc>::Type
314 {
315  typedef decltype(getRBForAdaptor<tRange>(iContainer, iNextFunc)) RBForAdaptor;
316  return RBForAdaptor(std::begin(iContainer), std::end(iContainer), iNextFunc);
317 }
318 
319 // ---------------------------------------------------------------------------
320 /*!
321  @brief 範囲ベースforを分割できるようにするためのレンジ生成
322 */
323 // ---------------------------------------------------------------------------
324 
325 template<class tContainer, class tNextFunc=internal::NopFunctor>
326 auto getRBForSeparator(tContainer&& iContainer, tNextFunc&& iNextFunc=internal::NopFunctor()) ->
327  typename internal::MakeRBForAdaptor<BasicRange, tContainer, tNextFunc>::Type
328 {
329  return getRBForAdaptor<BasicRange>(iContainer, iNextFunc);
330 }
331 
332 // ---------------------------------------------------------------------------
333 /*!
334  @brief 範囲ベースforを分割できるようにし、かつ、インデックス番号用レンジ生成
335 */
336 // ---------------------------------------------------------------------------
337 
338 template<class tContainer, class tNextFunc=internal::NopFunctor>
339 auto getRBForIndexer(tContainer&& iContainer, tNextFunc&& iNextFunc=internal::NopFunctor()) ->
340  typename internal::MakeRBForAdaptor<internal::Indexer, tContainer, tNextFunc>::Type
341 {
342  return getRBForAdaptor<internal::Indexer>(iContainer, iNextFunc);
343 }
344 
345 //############################################################################
346 // End
347 //############################################################################
348 
349 } // namespace theolizer
350 
351 // ***************************************************************************
352 // 警告抑止解除
353 // ***************************************************************************
354 
355 #ifdef _MSC_VER
356  #pragma warning(pop)
357 #endif
358 
359 #endif // THEOLIZER_INTERNAL_BASE_H
tIterator operator->()
Definition: rbfor.h:205
BasicRange(tIterator &&iBegin, tIterator &&iEnd)
Definition: rbfor.h:171
theolizer名前空間
Definition: base.h:53
auto getRBForIndexer(tContainer &&iContainer, tNextFunc &&iNextFunc=internal::NopFunctor()) -> typename internal::MakeRBForAdaptor< internal::Indexer, tContainer, tNextFunc >::Type
範囲ベースforを分割できるようにし、かつ、インデックス番号用レンジ生成
Definition: rbfor.h:339
範囲ベースfor用のRageを管理する基底クラス
Definition: rbfor.h:161
bool empty() const
Definition: rbfor.h:193
tIterator begin() const
Definition: rbfor.h:197
BasicRange & operator++()
Definition: rbfor.h:213
BasicRange operator++(int)
Definition: rbfor.h:221
auto getRBForSeparator(tContainer &&iContainer, tNextFunc &&iNextFunc=internal::NopFunctor()) -> typename internal::MakeRBForAdaptor< BasicRange, tContainer, tNextFunc >::Type
範囲ベースforを分割できるようにするためのレンジ生成
Definition: rbfor.h:326
tIterator end() const
Definition: rbfor.h:201
ValueType & front()
Definition: rbfor.h:189
auto getRBForAdaptor(tContainer &&iContainer, tNextFunc &&iNextFunc=internal::NopFunctor()) -> typename internal::MakeRBForAdaptor< tRange, tContainer, tNextFunc >::Type
汎用の範囲ベースfor用レンジ生成
Definition: rbfor.h:312
ValueType & operator*()
Definition: rbfor.h:209