AM Daemon ライブラリリファレンス
container.h
[詳解]
1 /// @file
2 /// @brief コンテナクラス関連の便利処理を提供するヘッダ。
3 ///
4 /// Copyright(C)SEGA
5 
6 #ifndef AMDAEMON_UTIL_CONTAINER_H
7 #define AMDAEMON_UTIL_CONTAINER_H
8 
9 #include "amdaemon/env.h"
10 
11 #include <algorithm>
12 #include <utility>
13 #include <type_traits>
14 #include <iterator>
15 #include <vector>
16 #include <bitset>
17 
18 namespace amdaemon
19 {
20 namespace util
21 {
22 /// @addtogroup g_util
23 /// @{
24 
25  namespace detail
26  {
27  /// @brief toContainer 関数の実処理を行うヘルパクラステンプレート。
28  /// @note 部分特殊化のためのクラス。
29  template<class DestContainer, class SrcContainer>
30  struct ContainerToContainer
31  {
32  template<class TheSrcContainer>
33  DestContainer operator()(TheSrcContainer&& src) const
34  {
35  using std::begin; // for ADL
36  using std::end; // for ADL
37 
38  return
39  DestContainer(
40  begin(std::forward<TheSrcContainer>(src)),
41  end(std::forward<TheSrcContainer>(src)));
42  }
43  };
44 
45  /// @brief toContainer 関数の実処理を行うヘルパクラステンプレート。
46  /// @note 同一コンテナ型用の部分特殊化。
47  template<class Container>
48  struct ContainerToContainer<Container, Container>
49  {
50  template<class TheSrcContainer>
51  Container operator()(TheSrcContainer&& src) const
52  {
53  return src;
54  }
55  };
56 
57  /// @brief toContainer 関数の実処理を行うヘルパクラステンプレート。
58  /// @note 部分特殊化のためのクラス。
59  template<class Container, class SizeType, class Getter>
60  struct GetterToContainer
61  {
62  /// @brief toContainer 関数の実処理を行う。
63  /// @param[in] count 要素数。
64  /// @param[in] getter インデックス値を引数に取る関数。
65  /// @return 作成されたコンテナ。
66  Container operator()(SizeType count, Getter&& getter) const
67  {
68  Container c;
69 
70  SizeType i = SizeType();
71  std::generate_n(
72  std::back_inserter(c),
73  count,
74  [&]() -> decltype(getter(i)) { return getter(i++); });
75 
76  return c;
77  }
78  };
79 
80  /// @brief toContainer 関数の実処理を行うヘルパクラステンプレート。
81  /// @note std::vector 型用の部分特殊化。
82  template<class T, class SizeType, class Getter>
83  struct GetterToContainer<std::vector<T>, SizeType, Getter>
84  {
85  /// @brief toContainer 関数の実処理を行う。
86  /// @param[in] count 要素数。
87  /// @param[in] getter インデックス値を引数に取る関数。
88  /// @return 作成されたコンテナ。
89  std::vector<T> operator()(SizeType count, Getter&& getter) const
90  {
91  std::vector<T> c;
92  c.reserve(count);
93 
94  SizeType i = SizeType();
95  std::generate_n(
96  std::back_inserter(c),
97  count,
98  [&]() -> decltype(getter(i)) { return getter(i++); });
99 
100  return c;
101  }
102  };
103  } // namespace detail
104 
105  /// @brief コンテナから指定した値を検索し、そのインデックスを返す。
106  /// @tparam Container 検索対象のコンテナ型。
107  /// @tparam T 検索する値の型。
108  /// @param[in] container 検索対象のコンテナ。
109  /// @param[in] target 検索する値。
110  /// @return インデックス。見つからなければ -1 。
111  template<class Container, class T>
112  std::ptrdiff_t findIndex(Container& container, const T& target)
113  {
114  using std::begin; // for ADL
115  using std::end; // for ADL
116 
117  const auto itrBegin = begin(container);
118  const auto itrEnd = end(container);
119  const auto itr = std::find(itrBegin, itrEnd, target);
120 
121  return static_cast<std::ptrdiff_t>((itr == itrEnd) ? -1 : std::distance(itrBegin, itr));
122  }
123 
124  /// @brief コンテナを別のコンテナ型に変換する。
125  /// @tparam DestContainer
126  /// 変換先のコンテナ型。
127  /// SrcContainer と同じ型であるか、
128  /// イテレータ範囲を受け取るコンストラクタが定義されていなければならない。
129  /// @tparam SrcContainer 変換元のコンテナ型。引数から推論される。
130  /// @param[in] src 変換元のコンテナ。
131  /// @return 変換されたコンテナ。
132  template<class DestContainer, class SrcContainer>
133  inline DestContainer toContainer(SrcContainer&& src)
134  {
135  return
136  ::amdaemon::util::detail::ContainerToContainer<DestContainer, SrcContainer>()(
137  std::forward<SrcContainer>(src));
138  }
139 
140  /// @brief インデックス値を引数に取る関数から得た値をコンテナに格納して返す。
141  /// @tparam Container
142  /// 変換先のコンテナ型。
143  /// std::back_insert_iterator による末尾への要素追加が可能でなければならない。
144  /// @tparam SizeType
145  /// 要素数を表す型。引数から推論される。
146  /// 一般的な整数型の要件を満たしていなければならない。
147  /// @tparam Getter
148  /// SizeType 型のインデックス値を引数に取る関数型。引数から推論される。
149  /// 戻り値の型を Container の要素型に変換可能でなければならない。
150  /// @param[in] count 要素数。
151  /// @param[in] getter インデックス値を引数に取る関数。
152  /// @return 作成されたコンテナ。
153  template<class Container, class SizeType, class Getter>
154  Container toContainer(SizeType count, Getter&& getter)
155  {
156  return
157  ::amdaemon::util::detail::GetterToContainer<Container, SizeType, Getter>()(
158  count,
159  std::forward<Getter>(getter));
160  }
161 
162  /// @brief 引数値を std::bitset 型に変換する。
163  /// @tparam N ビット数。
164  /// @tparam T
165  /// 引数の型。引数から推論される。
166  /// std::bitset<N> 型のコンストラクタに受け渡し可能でなければならない。
167  /// @param[in] value 引数値。
168  /// @return std::bitset<N> 型の値。
169  template<std::size_t N, class T>
170  inline std::bitset<N> toBitset(T&& value)
171  {
172  return std::bitset<N>(std::forward<T>(value));
173  }
174 
175  /// @brief 数値を std::bitset 型に変換する。
176  /// @tparam Integer 数値型。引数から推論される。組み込みの整数型でなければならない。
177  /// @param[in] value 数値。
178  /// @return std::bitset<sizeof(Integer) * 8> 型の値。
179  template<class Integer>
180  inline auto toBitset(Integer value)
181  ->
182  typename std::enable_if<
183  std::is_integral<Integer>::value,
184  std::bitset<sizeof(Integer) * 8>>::type
185  {
186  return toBitset<sizeof(Integer) * 8>(value);
187  }
188 
189 /// @}
190 } // namespace util
191 } // namespace amdaemon
192 
193 #endif // AMDAEMON_UTIL_CONTAINER_H
std::ptrdiff_t findIndex(Container &container, const T &target)
コンテナから指定した値を検索し、そのインデックスを返す。
Definition: container.h:112
Definition: AccessCode.h:202
Daemonライブラリの環境定義を行うヘッダ。
AM Daemon ライブラリクラス群の基底名前空間。
Definition: Log.h:13
DestContainer toContainer(SrcContainer &&src)
コンテナを別のコンテナ型に変換する。
Definition: container.h:133
std::bitset< N > toBitset(T &&value)
引数値を std::bitset 型に変換する。
Definition: container.h:170