1*38fd1498Szrj// <utility> -*- C++ -*- 2*38fd1498Szrj 3*38fd1498Szrj// Copyright (C) 2001-2018 Free Software Foundation, Inc. 4*38fd1498Szrj// 5*38fd1498Szrj// This file is part of the GNU ISO C++ Library. This library is free 6*38fd1498Szrj// software; you can redistribute it and/or modify it under the 7*38fd1498Szrj// terms of the GNU General Public License as published by the 8*38fd1498Szrj// Free Software Foundation; either version 3, or (at your option) 9*38fd1498Szrj// any later version. 10*38fd1498Szrj 11*38fd1498Szrj// This library is distributed in the hope that it will be useful, 12*38fd1498Szrj// but WITHOUT ANY WARRANTY; without even the implied warranty of 13*38fd1498Szrj// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14*38fd1498Szrj// GNU General Public License for more details. 15*38fd1498Szrj 16*38fd1498Szrj// Under Section 7 of GPL version 3, you are granted additional 17*38fd1498Szrj// permissions described in the GCC Runtime Library Exception, version 18*38fd1498Szrj// 3.1, as published by the Free Software Foundation. 19*38fd1498Szrj 20*38fd1498Szrj// You should have received a copy of the GNU General Public License and 21*38fd1498Szrj// a copy of the GCC Runtime Library Exception along with this program; 22*38fd1498Szrj// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23*38fd1498Szrj// <http://www.gnu.org/licenses/>. 24*38fd1498Szrj 25*38fd1498Szrj/* 26*38fd1498Szrj * 27*38fd1498Szrj * Copyright (c) 1994 28*38fd1498Szrj * Hewlett-Packard Company 29*38fd1498Szrj * 30*38fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 31*38fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 32*38fd1498Szrj * provided that the above copyright notice appear in all copies and 33*38fd1498Szrj * that both that copyright notice and this permission notice appear 34*38fd1498Szrj * in supporting documentation. Hewlett-Packard Company makes no 35*38fd1498Szrj * representations about the suitability of this software for any 36*38fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 37*38fd1498Szrj * 38*38fd1498Szrj * 39*38fd1498Szrj * Copyright (c) 1996,1997 40*38fd1498Szrj * Silicon Graphics Computer Systems, Inc. 41*38fd1498Szrj * 42*38fd1498Szrj * Permission to use, copy, modify, distribute and sell this software 43*38fd1498Szrj * and its documentation for any purpose is hereby granted without fee, 44*38fd1498Szrj * provided that the above copyright notice appear in all copies and 45*38fd1498Szrj * that both that copyright notice and this permission notice appear 46*38fd1498Szrj * in supporting documentation. Silicon Graphics makes no 47*38fd1498Szrj * representations about the suitability of this software for any 48*38fd1498Szrj * purpose. It is provided "as is" without express or implied warranty. 49*38fd1498Szrj */ 50*38fd1498Szrj 51*38fd1498Szrj/** @file include/utility 52*38fd1498Szrj * This is a Standard C++ Library header. 53*38fd1498Szrj */ 54*38fd1498Szrj 55*38fd1498Szrj#ifndef _GLIBCXX_UTILITY 56*38fd1498Szrj#define _GLIBCXX_UTILITY 1 57*38fd1498Szrj 58*38fd1498Szrj#pragma GCC system_header 59*38fd1498Szrj 60*38fd1498Szrj/** 61*38fd1498Szrj * @defgroup utilities Utilities 62*38fd1498Szrj * 63*38fd1498Szrj * Components deemed generally useful. Includes pair, tuple, 64*38fd1498Szrj * forward/move helpers, ratio, function object, metaprogramming and 65*38fd1498Szrj * type traits, time, date, and memory functions. 66*38fd1498Szrj */ 67*38fd1498Szrj 68*38fd1498Szrj#include <bits/c++config.h> 69*38fd1498Szrj#include <bits/stl_relops.h> 70*38fd1498Szrj#include <bits/stl_pair.h> 71*38fd1498Szrj 72*38fd1498Szrj#if __cplusplus >= 201103L 73*38fd1498Szrj 74*38fd1498Szrj#include <type_traits> 75*38fd1498Szrj#include <bits/move.h> 76*38fd1498Szrj#include <initializer_list> 77*38fd1498Szrj 78*38fd1498Szrjnamespace std _GLIBCXX_VISIBILITY(default) 79*38fd1498Szrj{ 80*38fd1498Szrj_GLIBCXX_BEGIN_NAMESPACE_VERSION 81*38fd1498Szrj 82*38fd1498Szrj /// Finds the size of a given tuple type. 83*38fd1498Szrj template<typename _Tp> 84*38fd1498Szrj struct tuple_size; 85*38fd1498Szrj 86*38fd1498Szrj // _GLIBCXX_RESOLVE_LIB_DEFECTS 87*38fd1498Szrj // 2313. tuple_size should always derive from integral_constant<size_t, N> 88*38fd1498Szrj // 2770. tuple_size<const T> specialization is not SFINAE compatible 89*38fd1498Szrj 90*38fd1498Szrj template<typename _Tp, 91*38fd1498Szrj typename _Up = typename remove_cv<_Tp>::type, 92*38fd1498Szrj typename = typename enable_if<is_same<_Tp, _Up>::value>::type, 93*38fd1498Szrj size_t = tuple_size<_Tp>::value> 94*38fd1498Szrj using __enable_if_has_tuple_size = _Tp; 95*38fd1498Szrj 96*38fd1498Szrj template<typename _Tp> 97*38fd1498Szrj struct tuple_size<const __enable_if_has_tuple_size<_Tp>> 98*38fd1498Szrj : public tuple_size<_Tp> { }; 99*38fd1498Szrj 100*38fd1498Szrj template<typename _Tp> 101*38fd1498Szrj struct tuple_size<volatile __enable_if_has_tuple_size<_Tp>> 102*38fd1498Szrj : public tuple_size<_Tp> { }; 103*38fd1498Szrj 104*38fd1498Szrj template<typename _Tp> 105*38fd1498Szrj struct tuple_size<const volatile __enable_if_has_tuple_size<_Tp>> 106*38fd1498Szrj : public tuple_size<_Tp> { }; 107*38fd1498Szrj 108*38fd1498Szrj /// Gives the type of the ith element of a given tuple type. 109*38fd1498Szrj template<std::size_t __i, typename _Tp> 110*38fd1498Szrj struct tuple_element; 111*38fd1498Szrj 112*38fd1498Szrj // Duplicate of C++14's tuple_element_t for internal use in C++11 mode 113*38fd1498Szrj template<std::size_t __i, typename _Tp> 114*38fd1498Szrj using __tuple_element_t = typename tuple_element<__i, _Tp>::type; 115*38fd1498Szrj 116*38fd1498Szrj template<std::size_t __i, typename _Tp> 117*38fd1498Szrj struct tuple_element<__i, const _Tp> 118*38fd1498Szrj { 119*38fd1498Szrj typedef typename add_const<__tuple_element_t<__i, _Tp>>::type type; 120*38fd1498Szrj }; 121*38fd1498Szrj 122*38fd1498Szrj template<std::size_t __i, typename _Tp> 123*38fd1498Szrj struct tuple_element<__i, volatile _Tp> 124*38fd1498Szrj { 125*38fd1498Szrj typedef typename add_volatile<__tuple_element_t<__i, _Tp>>::type type; 126*38fd1498Szrj }; 127*38fd1498Szrj 128*38fd1498Szrj template<std::size_t __i, typename _Tp> 129*38fd1498Szrj struct tuple_element<__i, const volatile _Tp> 130*38fd1498Szrj { 131*38fd1498Szrj typedef typename add_cv<__tuple_element_t<__i, _Tp>>::type type; 132*38fd1498Szrj }; 133*38fd1498Szrj 134*38fd1498Szrj#if __cplusplus > 201103L 135*38fd1498Szrj#define __cpp_lib_tuple_element_t 201402 136*38fd1498Szrj 137*38fd1498Szrj template<std::size_t __i, typename _Tp> 138*38fd1498Szrj using tuple_element_t = typename tuple_element<__i, _Tp>::type; 139*38fd1498Szrj#endif 140*38fd1498Szrj 141*38fd1498Szrj // Various functions which give std::pair a tuple-like interface. 142*38fd1498Szrj 143*38fd1498Szrj /// Partial specialization for std::pair 144*38fd1498Szrj template<typename _T1, typename _T2> 145*38fd1498Szrj struct __is_tuple_like_impl<std::pair<_T1, _T2>> : true_type 146*38fd1498Szrj { }; 147*38fd1498Szrj 148*38fd1498Szrj /// Partial specialization for std::pair 149*38fd1498Szrj template<class _Tp1, class _Tp2> 150*38fd1498Szrj struct tuple_size<std::pair<_Tp1, _Tp2>> 151*38fd1498Szrj : public integral_constant<std::size_t, 2> { }; 152*38fd1498Szrj 153*38fd1498Szrj /// Partial specialization for std::pair 154*38fd1498Szrj template<class _Tp1, class _Tp2> 155*38fd1498Szrj struct tuple_element<0, std::pair<_Tp1, _Tp2>> 156*38fd1498Szrj { typedef _Tp1 type; }; 157*38fd1498Szrj 158*38fd1498Szrj /// Partial specialization for std::pair 159*38fd1498Szrj template<class _Tp1, class _Tp2> 160*38fd1498Szrj struct tuple_element<1, std::pair<_Tp1, _Tp2>> 161*38fd1498Szrj { typedef _Tp2 type; }; 162*38fd1498Szrj 163*38fd1498Szrj template<std::size_t _Int> 164*38fd1498Szrj struct __pair_get; 165*38fd1498Szrj 166*38fd1498Szrj template<> 167*38fd1498Szrj struct __pair_get<0> 168*38fd1498Szrj { 169*38fd1498Szrj template<typename _Tp1, typename _Tp2> 170*38fd1498Szrj static constexpr _Tp1& 171*38fd1498Szrj __get(std::pair<_Tp1, _Tp2>& __pair) noexcept 172*38fd1498Szrj { return __pair.first; } 173*38fd1498Szrj 174*38fd1498Szrj template<typename _Tp1, typename _Tp2> 175*38fd1498Szrj static constexpr _Tp1&& 176*38fd1498Szrj __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept 177*38fd1498Szrj { return std::forward<_Tp1>(__pair.first); } 178*38fd1498Szrj 179*38fd1498Szrj template<typename _Tp1, typename _Tp2> 180*38fd1498Szrj static constexpr const _Tp1& 181*38fd1498Szrj __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept 182*38fd1498Szrj { return __pair.first; } 183*38fd1498Szrj 184*38fd1498Szrj template<typename _Tp1, typename _Tp2> 185*38fd1498Szrj static constexpr const _Tp1&& 186*38fd1498Szrj __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept 187*38fd1498Szrj { return std::forward<const _Tp1>(__pair.first); } 188*38fd1498Szrj }; 189*38fd1498Szrj 190*38fd1498Szrj template<> 191*38fd1498Szrj struct __pair_get<1> 192*38fd1498Szrj { 193*38fd1498Szrj template<typename _Tp1, typename _Tp2> 194*38fd1498Szrj static constexpr _Tp2& 195*38fd1498Szrj __get(std::pair<_Tp1, _Tp2>& __pair) noexcept 196*38fd1498Szrj { return __pair.second; } 197*38fd1498Szrj 198*38fd1498Szrj template<typename _Tp1, typename _Tp2> 199*38fd1498Szrj static constexpr _Tp2&& 200*38fd1498Szrj __move_get(std::pair<_Tp1, _Tp2>&& __pair) noexcept 201*38fd1498Szrj { return std::forward<_Tp2>(__pair.second); } 202*38fd1498Szrj 203*38fd1498Szrj template<typename _Tp1, typename _Tp2> 204*38fd1498Szrj static constexpr const _Tp2& 205*38fd1498Szrj __const_get(const std::pair<_Tp1, _Tp2>& __pair) noexcept 206*38fd1498Szrj { return __pair.second; } 207*38fd1498Szrj 208*38fd1498Szrj template<typename _Tp1, typename _Tp2> 209*38fd1498Szrj static constexpr const _Tp2&& 210*38fd1498Szrj __const_move_get(const std::pair<_Tp1, _Tp2>&& __pair) noexcept 211*38fd1498Szrj { return std::forward<const _Tp2>(__pair.second); } 212*38fd1498Szrj }; 213*38fd1498Szrj 214*38fd1498Szrj template<std::size_t _Int, class _Tp1, class _Tp2> 215*38fd1498Szrj constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& 216*38fd1498Szrj get(std::pair<_Tp1, _Tp2>& __in) noexcept 217*38fd1498Szrj { return __pair_get<_Int>::__get(__in); } 218*38fd1498Szrj 219*38fd1498Szrj template<std::size_t _Int, class _Tp1, class _Tp2> 220*38fd1498Szrj constexpr typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& 221*38fd1498Szrj get(std::pair<_Tp1, _Tp2>&& __in) noexcept 222*38fd1498Szrj { return __pair_get<_Int>::__move_get(std::move(__in)); } 223*38fd1498Szrj 224*38fd1498Szrj template<std::size_t _Int, class _Tp1, class _Tp2> 225*38fd1498Szrj constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type& 226*38fd1498Szrj get(const std::pair<_Tp1, _Tp2>& __in) noexcept 227*38fd1498Szrj { return __pair_get<_Int>::__const_get(__in); } 228*38fd1498Szrj 229*38fd1498Szrj template<std::size_t _Int, class _Tp1, class _Tp2> 230*38fd1498Szrj constexpr const typename tuple_element<_Int, std::pair<_Tp1, _Tp2>>::type&& 231*38fd1498Szrj get(const std::pair<_Tp1, _Tp2>&& __in) noexcept 232*38fd1498Szrj { return __pair_get<_Int>::__const_move_get(std::move(__in)); } 233*38fd1498Szrj 234*38fd1498Szrj#if __cplusplus > 201103L 235*38fd1498Szrj 236*38fd1498Szrj#define __cpp_lib_tuples_by_type 201304 237*38fd1498Szrj 238*38fd1498Szrj template <typename _Tp, typename _Up> 239*38fd1498Szrj constexpr _Tp& 240*38fd1498Szrj get(pair<_Tp, _Up>& __p) noexcept 241*38fd1498Szrj { return __p.first; } 242*38fd1498Szrj 243*38fd1498Szrj template <typename _Tp, typename _Up> 244*38fd1498Szrj constexpr const _Tp& 245*38fd1498Szrj get(const pair<_Tp, _Up>& __p) noexcept 246*38fd1498Szrj { return __p.first; } 247*38fd1498Szrj 248*38fd1498Szrj template <typename _Tp, typename _Up> 249*38fd1498Szrj constexpr _Tp&& 250*38fd1498Szrj get(pair<_Tp, _Up>&& __p) noexcept 251*38fd1498Szrj { return std::move(__p.first); } 252*38fd1498Szrj 253*38fd1498Szrj template <typename _Tp, typename _Up> 254*38fd1498Szrj constexpr const _Tp&& 255*38fd1498Szrj get(const pair<_Tp, _Up>&& __p) noexcept 256*38fd1498Szrj { return std::move(__p.first); } 257*38fd1498Szrj 258*38fd1498Szrj template <typename _Tp, typename _Up> 259*38fd1498Szrj constexpr _Tp& 260*38fd1498Szrj get(pair<_Up, _Tp>& __p) noexcept 261*38fd1498Szrj { return __p.second; } 262*38fd1498Szrj 263*38fd1498Szrj template <typename _Tp, typename _Up> 264*38fd1498Szrj constexpr const _Tp& 265*38fd1498Szrj get(const pair<_Up, _Tp>& __p) noexcept 266*38fd1498Szrj { return __p.second; } 267*38fd1498Szrj 268*38fd1498Szrj template <typename _Tp, typename _Up> 269*38fd1498Szrj constexpr _Tp&& 270*38fd1498Szrj get(pair<_Up, _Tp>&& __p) noexcept 271*38fd1498Szrj { return std::move(__p.second); } 272*38fd1498Szrj 273*38fd1498Szrj template <typename _Tp, typename _Up> 274*38fd1498Szrj constexpr const _Tp&& 275*38fd1498Szrj get(const pair<_Up, _Tp>&& __p) noexcept 276*38fd1498Szrj { return std::move(__p.second); } 277*38fd1498Szrj 278*38fd1498Szrj#define __cpp_lib_exchange_function 201304 279*38fd1498Szrj 280*38fd1498Szrj /// Assign @p __new_val to @p __obj and return its previous value. 281*38fd1498Szrj template <typename _Tp, typename _Up = _Tp> 282*38fd1498Szrj inline _Tp 283*38fd1498Szrj exchange(_Tp& __obj, _Up&& __new_val) 284*38fd1498Szrj { return std::__exchange(__obj, std::forward<_Up>(__new_val)); } 285*38fd1498Szrj#endif 286*38fd1498Szrj 287*38fd1498Szrj // Stores a tuple of indices. Used by tuple and pair, and by bind() to 288*38fd1498Szrj // extract the elements in a tuple. 289*38fd1498Szrj template<size_t... _Indexes> struct _Index_tuple { }; 290*38fd1498Szrj 291*38fd1498Szrj#ifdef __has_builtin 292*38fd1498Szrj# if __has_builtin(__make_integer_seq) 293*38fd1498Szrj# define _GLIBCXX_USE_MAKE_INTEGER_SEQ 1 294*38fd1498Szrj# endif 295*38fd1498Szrj#endif 296*38fd1498Szrj 297*38fd1498Szrj // Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. 298*38fd1498Szrj template<size_t _Num> 299*38fd1498Szrj struct _Build_index_tuple 300*38fd1498Szrj { 301*38fd1498Szrj#if _GLIBCXX_USE_MAKE_INTEGER_SEQ 302*38fd1498Szrj template<typename, size_t... _Indices> 303*38fd1498Szrj using _IdxTuple = _Index_tuple<_Indices...>; 304*38fd1498Szrj 305*38fd1498Szrj using __type = __make_integer_seq<_IdxTuple, size_t, _Num>; 306*38fd1498Szrj#else 307*38fd1498Szrj using __type = _Index_tuple<__integer_pack(_Num)...>; 308*38fd1498Szrj#endif 309*38fd1498Szrj }; 310*38fd1498Szrj 311*38fd1498Szrj#if __cplusplus > 201103L 312*38fd1498Szrj 313*38fd1498Szrj#define __cpp_lib_integer_sequence 201304 314*38fd1498Szrj 315*38fd1498Szrj /// Class template integer_sequence 316*38fd1498Szrj template<typename _Tp, _Tp... _Idx> 317*38fd1498Szrj struct integer_sequence 318*38fd1498Szrj { 319*38fd1498Szrj typedef _Tp value_type; 320*38fd1498Szrj static constexpr size_t size() noexcept { return sizeof...(_Idx); } 321*38fd1498Szrj }; 322*38fd1498Szrj 323*38fd1498Szrj /// Alias template make_integer_sequence 324*38fd1498Szrj template<typename _Tp, _Tp _Num> 325*38fd1498Szrj using make_integer_sequence 326*38fd1498Szrj#if _GLIBCXX_USE_MAKE_INTEGER_SEQ 327*38fd1498Szrj = __make_integer_seq<integer_sequence, _Tp, _Num>; 328*38fd1498Szrj#else 329*38fd1498Szrj = integer_sequence<_Tp, __integer_pack(_Num)...>; 330*38fd1498Szrj#endif 331*38fd1498Szrj 332*38fd1498Szrj#undef _GLIBCXX_USE_MAKE_INTEGER_SEQ 333*38fd1498Szrj 334*38fd1498Szrj /// Alias template index_sequence 335*38fd1498Szrj template<size_t... _Idx> 336*38fd1498Szrj using index_sequence = integer_sequence<size_t, _Idx...>; 337*38fd1498Szrj 338*38fd1498Szrj /// Alias template make_index_sequence 339*38fd1498Szrj template<size_t _Num> 340*38fd1498Szrj using make_index_sequence = make_integer_sequence<size_t, _Num>; 341*38fd1498Szrj 342*38fd1498Szrj /// Alias template index_sequence_for 343*38fd1498Szrj template<typename... _Types> 344*38fd1498Szrj using index_sequence_for = make_index_sequence<sizeof...(_Types)>; 345*38fd1498Szrj#endif 346*38fd1498Szrj 347*38fd1498Szrj#if __cplusplus > 201402L 348*38fd1498Szrj 349*38fd1498Szrj struct in_place_t { 350*38fd1498Szrj explicit in_place_t() = default; 351*38fd1498Szrj }; 352*38fd1498Szrj 353*38fd1498Szrj inline constexpr in_place_t in_place{}; 354*38fd1498Szrj 355*38fd1498Szrj template<typename _Tp> struct in_place_type_t 356*38fd1498Szrj { 357*38fd1498Szrj explicit in_place_type_t() = default; 358*38fd1498Szrj }; 359*38fd1498Szrj 360*38fd1498Szrj template<typename _Tp> 361*38fd1498Szrj inline constexpr in_place_type_t<_Tp> in_place_type{}; 362*38fd1498Szrj 363*38fd1498Szrj template<size_t _Idx> struct in_place_index_t 364*38fd1498Szrj { 365*38fd1498Szrj explicit in_place_index_t() = default; 366*38fd1498Szrj }; 367*38fd1498Szrj 368*38fd1498Szrj template<size_t _Idx> 369*38fd1498Szrj inline constexpr in_place_index_t<_Idx> in_place_index{}; 370*38fd1498Szrj 371*38fd1498Szrj template<typename> 372*38fd1498Szrj struct __is_in_place_type_impl : false_type 373*38fd1498Szrj { }; 374*38fd1498Szrj 375*38fd1498Szrj template<typename _Tp> 376*38fd1498Szrj struct __is_in_place_type_impl<in_place_type_t<_Tp>> : true_type 377*38fd1498Szrj { }; 378*38fd1498Szrj 379*38fd1498Szrj template<typename _Tp> 380*38fd1498Szrj struct __is_in_place_type 381*38fd1498Szrj : public __is_in_place_type_impl<_Tp> 382*38fd1498Szrj { }; 383*38fd1498Szrj 384*38fd1498Szrj#define __cpp_lib_as_const 201510 385*38fd1498Szrj template<typename _Tp> 386*38fd1498Szrj constexpr add_const_t<_Tp>& as_const(_Tp& __t) noexcept { return __t; } 387*38fd1498Szrj 388*38fd1498Szrj template<typename _Tp> 389*38fd1498Szrj void as_const(const _Tp&&) = delete; 390*38fd1498Szrj 391*38fd1498Szrj#endif // C++17 392*38fd1498Szrj 393*38fd1498Szrj_GLIBCXX_END_NAMESPACE_VERSION 394*38fd1498Szrj} // namespace 395*38fd1498Szrj 396*38fd1498Szrj#endif 397*38fd1498Szrj 398*38fd1498Szrj#endif /* _GLIBCXX_UTILITY */ 399