1 // <utility> -*- C++ -*- 2 3 // Copyright (C) 2001-2014 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 template<class _Tp1, class _Tp2> 89 struct tuple_size<std::pair<_Tp1, _Tp2>> 90 : public integral_constant<std::size_t, 2> { }; 91 92 template<class _Tp1, class _Tp2> 93 struct tuple_element<0, std::pair<_Tp1, _Tp2>> 94 { typedef _Tp1 type; }; 95 96 template<class _Tp1, class _Tp2> 97 struct tuple_element<1, std::pair<_Tp1, _Tp2>> 98 { typedef _Tp2 type; }; 99 100 template<std::size_t _Int> 101 struct __pair_get; 102 103 template<> 104 struct __pair_get<0> 105 { 106 template<typename _Tp1, typename _Tp2> 107 static constexpr _Tp1& 108 __get(std::pair<_Tp1, _Tp2>& __pair) noexcept 109 { return __pair.first; } 110 111 template<typename _Tp1, typename _Tp2> 112 static constexpr _Tp1&& 113 __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept 114 { return std::forward<_Tp1>(__pair.first); } 115 116 template<typename _Tp1, typename _Tp2> 117 static constexpr const _Tp1& 118 __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept 119 { return __pair.first; } 120 }; 121 122 template<> 123 struct __pair_get<1> 124 { 125 template<typename _Tp1, typename _Tp2> 126 static constexpr _Tp2& 127 __get(std::pair<_Tp1, _Tp2>& __pair) noexcept 128 { return __pair.second; } 129 130 template<typename _Tp1, typename _Tp2> 131 static constexpr _Tp2&& 132 __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept 133 { return std::forward<_Tp2>(__pair.second); } 134 135 template<typename _Tp1, typename _Tp2> 136 static constexpr const _Tp2& 137 __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept 138 { return __pair.second; } 139 }; 140 141 template<std::size_t _Int, class _Tp1, class _Tp2> 142 constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& 143 get(std::pair<_Tp1, _Tp2>& __in) noexcept 144 { return __pair_get<_Int>::__get(__in); } 145 146 template<std::size_t _Int, class _Tp1, class _Tp2> 147 constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& 148 get(std::pair<_Tp1, _Tp2>&& __in) noexcept 149 { return __pair_get<_Int>::__move_get(std::move(__in)); } 150 151 template<std::size_t _Int, class _Tp1, class _Tp2> 152 constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& 153 get(const std::pair<_Tp1, _Tp2>& __in) noexcept 154 { return __pair_get<_Int>::__const_get(__in); } 155 156 #if __cplusplus > 201103L 157 158 #define __cpp_lib_tuples_by_type 201304 159 160 template <typename _Tp, typename _Up> 161 constexpr _Tp& 162 get(pair<_Tp, _Up>& __p) noexcept 163 { return __p.first; } 164 165 template <typename _Tp, typename _Up> 166 constexpr const _Tp& 167 get(const pair<_Tp, _Up>& __p) noexcept 168 { return __p.first; } 169 170 template <typename _Tp, typename _Up> 171 constexpr _Tp&& 172 get(pair<_Tp, _Up>&& __p) noexcept 173 { return std::move(__p.first); } 174 175 template <typename _Tp, typename _Up> 176 constexpr _Tp& 177 get(pair<_Up, _Tp>& __p) noexcept 178 { return __p.second; } 179 180 template <typename _Tp, typename _Up> 181 constexpr const _Tp& 182 get(const pair<_Up, _Tp>& __p) noexcept 183 { return __p.second; } 184 185 template <typename _Tp, typename _Up> 186 constexpr _Tp&& 187 get(pair<_Up, _Tp>&& __p) noexcept 188 { return std::move(__p.second); } 189 190 #define __cpp_lib_exchange_function 201304 191 192 /// Assign @p __new_val to @p __obj and return its previous value. 193 template <typename _Tp, typename _Up = _Tp> 194 inline _Tp 195 exchange(_Tp& __obj, _Up&& __new_val) 196 { 197 _Tp __old_val = std::move(__obj); 198 __obj = std::forward<_Up>(__new_val); 199 return __old_val; 200 } 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