1 | // <utility> -*- C++ -*- |
---|---|

2 | |

3 | // Copyright (C) 2001-2015 Free Software Foundation, Inc. |

4 | // |

5 | // This file is part of the GNU ISO C++ Library. This library is free |

6 | // software; you can redistribute it and/or modify it under the |

7 | // terms of the GNU General Public License as published by the |

8 | // Free Software Foundation; either version 3, or (at your option) |

9 | // any later version. |

10 | |

11 | // This library is distributed in the hope that it will be useful, |

12 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |

13 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |

14 | // GNU General Public License for more details. |

15 | |

16 | // Under Section 7 of GPL version 3, you are granted additional |

17 | // permissions described in the GCC Runtime Library Exception, version |

18 | // 3.1, as published by the Free Software Foundation. |

19 | |

20 | // You should have received a copy of the GNU General Public License and |

21 | // a copy of the GCC Runtime Library Exception along with this program; |

22 | // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see |

23 | // <http://www.gnu.org/licenses/>. |

24 | |

25 | /* |

26 | * |

27 | * Copyright (c) 1994 |

28 | * Hewlett-Packard Company |

29 | * |

30 | * Permission to use, copy, modify, distribute and sell this software |

31 | * and its documentation for any purpose is hereby granted without fee, |

32 | * provided that the above copyright notice appear in all copies and |

33 | * that both that copyright notice and this permission notice appear |

34 | * in supporting documentation. Hewlett-Packard Company makes no |

35 | * representations about the suitability of this software for any |

36 | * purpose. It is provided "as is" without express or implied warranty. |

37 | * |

38 | * |

39 | * Copyright (c) 1996,1997 |

40 | * Silicon Graphics Computer Systems, Inc. |

41 | * |

42 | * Permission to use, copy, modify, distribute and sell this software |

43 | * and its documentation for any purpose is hereby granted without fee, |

44 | * provided that the above copyright notice appear in all copies and |

45 | * that both that copyright notice and this permission notice appear |

46 | * in supporting documentation. Silicon Graphics makes no |

47 | * representations about the suitability of this software for any |

48 | * purpose. It is provided "as is" without express or implied warranty. |

49 | */ |

50 | |

51 | /** @file include/utility |

52 | * This is a Standard C++ Library header. |

53 | */ |

54 | |

55 | #ifndef _GLIBCXX_UTILITY |

56 | #define _GLIBCXX_UTILITY 1 |

57 | |

58 | #pragma GCC system_header |

59 | |

60 | /** |

61 | * @defgroup utilities Utilities |

62 | * |

63 | * Components deemed generally useful. Includes pair, tuple, |

64 | * forward/move helpers, ratio, function object, metaprogramming and |

65 | * type traits, time, date, and memory functions. |

66 | */ |

67 | |

68 | #include <bits/c++config.h> |

69 | #include <bits/stl_relops.h> |

70 | #include <bits/stl_pair.h> |

71 | |

72 | #if __cplusplus >= 201103L |

73 | |

74 | #include <bits/move.h> |

75 | #include <initializer_list> |

76 | |

77 | namespace std _GLIBCXX_VISIBILITY(default) |

78 | { |

79 | _GLIBCXX_BEGIN_NAMESPACE_VERSION |

80 | |

81 | template<class _Tp> |

82 | class tuple_size; |

83 | |

84 | template<std::size_t _Int, class _Tp> |

85 | class tuple_element; |

86 | |

87 | // Various functions which give std::pair a tuple-like interface. |

88 | |

89 | /// Partial specialization for std::pair |

90 | template<class _Tp1, class _Tp2> |

91 | struct tuple_size<std::pair<_Tp1, _Tp2>> |

92 | : public integral_constant<std::size_t, 2> { }; |

93 | |

94 | /// Partial specialization for std::pair |

95 | template<class _Tp1, class _Tp2> |

96 | struct tuple_element<0, std::pair<_Tp1, _Tp2>> |

97 | { typedef _Tp1 type; }; |

98 | |

99 | /// Partial specialization for std::pair |

100 | template<class _Tp1, class _Tp2> |

101 | struct tuple_element<1, std::pair<_Tp1, _Tp2>> |

102 | { typedef _Tp2 type; }; |

103 | |

104 | template<std::size_t _Int> |

105 | struct __pair_get; |

106 | |

107 | template<> |

108 | struct __pair_get<0> |

109 | { |

110 | template<typename _Tp1, typename _Tp2> |

111 | static constexpr _Tp1& |

112 | __get(std::pair<_Tp1, _Tp2>& __pair) noexcept |

113 | { return __pair.first; } |

114 | |

115 | template<typename _Tp1, typename _Tp2> |

116 | static constexpr _Tp1&& |

117 | __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept |

118 | { return std::forward<_Tp1>(__pair.first); } |

119 | |

120 | template<typename _Tp1, typename _Tp2> |

121 | static constexpr const _Tp1& |

122 | __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept |

123 | { return __pair.first; } |

124 | }; |

125 | |

126 | template<> |

127 | struct __pair_get<1> |

128 | { |

129 | template<typename _Tp1, typename _Tp2> |

130 | static constexpr _Tp2& |

131 | __get(std::pair<_Tp1, _Tp2>& __pair) noexcept |

132 | { return __pair.second; } |

133 | |

134 | template<typename _Tp1, typename _Tp2> |

135 | static constexpr _Tp2&& |

136 | __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept |

137 | { return std::forward<_Tp2>(__pair.second); } |

138 | |

139 | template<typename _Tp1, typename _Tp2> |

140 | static constexpr const _Tp2& |

141 | __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept |

142 | { return __pair.second; } |

143 | }; |

144 | |

145 | template<std::size_t _Int, class _Tp1, class _Tp2> |

146 | constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& |

147 | get(std::pair<_Tp1, _Tp2>& __in) noexcept |

148 | { return __pair_get<_Int>::__get(__in); } |

149 | |

150 | template<std::size_t _Int, class _Tp1, class _Tp2> |

151 | constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& |

152 | get(std::pair<_Tp1, _Tp2>&& __in) noexcept |

153 | { return __pair_get<_Int>::__move_get(std::move(__in)); } |

154 | |

155 | template<std::size_t _Int, class _Tp1, class _Tp2> |

156 | constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& |

157 | get(const std::pair<_Tp1, _Tp2>& __in) noexcept |

158 | { return __pair_get<_Int>::__const_get(__in); } |

159 | |

160 | #if __cplusplus > 201103L |

161 | |

162 | #define __cpp_lib_tuples_by_type 201304 |

163 | |

164 | template <typename _Tp, typename _Up> |

165 | constexpr _Tp& |

166 | get(pair<_Tp, _Up>& __p) noexcept |

167 | { return __p.first; } |

168 | |

169 | template <typename _Tp, typename _Up> |

170 | constexpr const _Tp& |

171 | get(const pair<_Tp, _Up>& __p) noexcept |

172 | { return __p.first; } |

173 | |

174 | template <typename _Tp, typename _Up> |

175 | constexpr _Tp&& |

176 | get(pair<_Tp, _Up>&& __p) noexcept |

177 | { return std::move(__p.first); } |

178 | |

179 | template <typename _Tp, typename _Up> |

180 | constexpr _Tp& |

181 | get(pair<_Up, _Tp>& __p) noexcept |

182 | { return __p.second; } |

183 | |

184 | template <typename _Tp, typename _Up> |

185 | constexpr const _Tp& |

186 | get(const pair<_Up, _Tp>& __p) noexcept |

187 | { return __p.second; } |

188 | |

189 | template <typename _Tp, typename _Up> |

190 | constexpr _Tp&& |

191 | get(pair<_Up, _Tp>&& __p) noexcept |

192 | { return std::move(__p.second); } |

193 | |

194 | #define __cpp_lib_exchange_function 201304 |

195 | |

196 | /// Assign @p __new_val to @p __obj and return its previous value. |

197 | template <typename _Tp, typename _Up = _Tp> |

198 | inline _Tp |

199 | exchange(_Tp& __obj, _Up&& __new_val) |

200 | { return std::__exchange(__obj, std::forward<_Up>(__new_val)); } |

201 | #endif |

202 | |

203 | // Stores a tuple of indices. Used by tuple and pair, and by bind() to |

204 | // extract the elements in a tuple. |

205 | template<size_t... _Indexes> |

206 | struct _Index_tuple |

207 | { |

208 | typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next; |

209 | }; |

210 | |

211 | // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. |

212 | template<size_t _Num> |

213 | struct _Build_index_tuple |

214 | { |

215 | typedef typename _Build_index_tuple<_Num - 1>::__type::__next __type; |

216 | }; |

217 | |

218 | template<> |

219 | struct _Build_index_tuple<0> |

220 | { |

221 | typedef _Index_tuple<> __type; |

222 | }; |

223 | |

224 | #if __cplusplus > 201103L |

225 | |

226 | #define __cpp_lib_integer_sequence 201304 |

227 | |

228 | /// Class template integer_sequence |

229 | template<typename _Tp, _Tp... _Idx> |

230 | struct integer_sequence |

231 | { |

232 | typedef _Tp value_type; |

233 | static constexpr size_t size() { return sizeof...(_Idx); } |

234 | }; |

235 | |

236 | template<typename _Tp, _Tp _Num, |

237 | typename _ISeq = typename _Build_index_tuple<_Num>::__type> |

238 | struct _Make_integer_sequence; |

239 | |

240 | template<typename _Tp, _Tp _Num, size_t... _Idx> |

241 | struct _Make_integer_sequence<_Tp, _Num, _Index_tuple<_Idx...>> |

242 | { |

243 | static_assert( _Num >= 0, |

244 | "Cannot make integer sequence of negative length"); |

245 | |

246 | typedef integer_sequence<_Tp, static_cast<_Tp>(_Idx)...> __type; |

247 | }; |

248 | |

249 | /// Alias template make_integer_sequence |

250 | template<typename _Tp, _Tp _Num> |

251 | using make_integer_sequence |

252 | = typename _Make_integer_sequence<_Tp, _Num>::__type; |

253 | |

254 | /// Alias template index_sequence |

255 | template<size_t... _Idx> |

256 | using index_sequence = integer_sequence<size_t, _Idx...>; |

257 | |

258 | /// Alias template make_index_sequence |

259 | template<size_t _Num> |

260 | using make_index_sequence = make_integer_sequence<size_t, _Num>; |

261 | |

262 | /// Alias template index_sequence_for |

263 | template<typename... _Types> |

264 | using index_sequence_for = make_index_sequence<sizeof...(_Types)>; |

265 | #endif |

266 | |

267 | _GLIBCXX_END_NAMESPACE_VERSION |

268 | } // namespace |

269 | |

270 | #endif |

271 | |

272 | #endif /* _GLIBCXX_UTILITY */ |

273 |