[Init][初始化仓库]

This commit is contained in:
like 2025-06-10 15:49:49 +08:00
commit c2fd377810
5910 changed files with 1971093 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
out/

24
CMakeLists.txt Normal file
View File

@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.10)
set(CMAKE_C_COMPILER "${ROOT_DIR}/thirdparty/aarch64-none-linux-gnu-103/bin/aarch64-none-linux-gnu-gcc")
set(CMAKE_CXX_COMPILER "${ROOT_DIR}/thirdparty/aarch64-none-linux-gnu-103/bin/aarch64-none-linux-gnu-g++")
project(auapp
VERSION 1.0
DESCRIPTION "auhui app"
LANGUAGES CXX
)
set(ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(INCLUDE_DIR ${ROOT_DIR}/include)
set(SOURCES ${ROOT_DIR}/src/main/main.cc)
include(${ROOT_DIR}/src/usb_camera/CMakeLists.txt)
include_directories(
${INCLUDE_DIR}
)
add_executable(auapp
${SOURCES}
)

1
README.md Normal file
View File

@ -0,0 +1 @@
#auhui app

11
build.sh Executable file
View File

@ -0,0 +1,11 @@
#!/bin/bash
if [ -d out ]; then
rm -rf out
fi
mkdir out
cd out
cmake ..
make -j$(nproc)

11
src/main/main.cc Normal file
View File

@ -0,0 +1,11 @@
#include <iostream>
#include <string>
#include "usb_camera.h"
int main()
{
UsbCamera camera;
std::cout << "Hello, World!" << std::endl;
return 0;
}

View File

@ -0,0 +1,5 @@
list(APPEND INCLUDE_DIR "${ROOT_DIR}/src/usb_camera")
list(APPEND SOURCES
"${ROOT_DIR}/src/usb_camera/usb_camera.cc"
"${ROOT_DIR}/src/usb_camera/usb_camera.h"
)

View File

@ -0,0 +1,10 @@
#include <iostream>
#include "usb_camera.h"
UsbCamera::UsbCamera() {
std::cout << "UsbCamera initialized." << std::endl;
}
UsbCamera::~UsbCamera() {
std::cout << "UsbCamera destroyed." << std::endl;
}

View File

@ -0,0 +1,11 @@
#pragma once
#include <iostream>
class UsbCamera {
public:
UsbCamera();
~UsbCamera();
private:
std::string camera_name_;
};

View File

@ -0,0 +1,13 @@
gmp_configure=--disable-maintainer-mode --disable-shared --prefix=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools
mpfr_configure=--disable-maintainer-mode --disable-shared --prefix=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-gmp=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools
mpc_configure=--disable-maintainer-mode --disable-shared --prefix=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-gmp=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-mpfr=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools
isl_configure=--disable-maintainer-mode --disable-shared --prefix=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-gmp-prefix=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools
binutils_configure=--enable-64-bit-bfd --enable-targets=arm-none-eabi,aarch64_be-none-linux-gnu,aarch64_be-none-elf,aarch64-none-linux-gnu,aarch64-none-linux-gnu_ilp32,aarch64-none-elf --target=aarch64-none-linux-gnu --with-bugurl="https://bugs.linaro.org/" --enable-gold --enable-initfini-array --enable-plugins --disable-doc --disable-gdb --disable-gdbtk --disable-nls --disable-tui --disable-werror --without-gdb --without-python --without-x --prefix= --with-build-sysroot=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc --with-sysroot=/aarch64-none-linux-gnu/libc
gcc1_configure=--target=aarch64-none-linux-gnu --prefix= --with-sysroot=/aarch64-none-linux-gnu/libc --with-build-sysroot=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc --without-headers --with-newlib --with-bugurl="https://bugs.linaro.org/" --without-cloog --without-isl --disable-shared --disable-threads --disable-libatomic --disable-libsanitizer --disable-libssp --disable-libgomp --disable-libmudflap --disable-libquadmath --enable-checking=yes --enable-languages=c --with-gmp=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-mpfr=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-mpc=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --enable-fix-cortex-a53-843419
gcc2_configure=--target=aarch64-none-linux-gnu --prefix= --with-sysroot=/aarch64-none-linux-gnu/libc --with-build-sysroot=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc --with-bugurl="https://bugs.linaro.org/" --enable-shared --disable-libatomic --without-cloog --without-isl --disable-libssp --disable-libgomp --disable-libmudflap --disable-libquadmath --enable-checking=yes --enable-languages=c --with-gmp=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-mpfr=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-mpc=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --enable-fix-cortex-a53-843419
glibc_configure=--enable-shared --with-tls --disable-profile --disable-omitfp --disable-bounded --disable-sanity-checks --prefix=/usr --with-headers=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc/usr/include --includedir=/usr/include --with-pkgversion=GNU Toolchain for the A-profile Architecture 10.3-2021.07 (arm-10.29) --build=x86_64-unknown-linux-gnu --host=aarch64-none-linux-gnu --disable-werror --enable-obsolete-rpc --disable-profile --without-gd --without-cvs --without-selinux
gcc3_configure=--target=aarch64-none-linux-gnu --prefix= --with-sysroot=/aarch64-none-linux-gnu/libc --with-build-sysroot=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc --with-bugurl="https://bugs.linaro.org/" --enable-gnu-indirect-function --enable-shared --disable-libssp --disable-libmudflap --enable-checking=release --enable-languages=c,c++,fortran --with-gmp=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-mpfr=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-mpc=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-isl=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --enable-fix-cortex-a53-843419
gcc4_configure=--target=aarch64-none-linux-gnu --prefix= --with-sysroot=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc --with-bugurl="https://bugs.linaro.org/" --enable-shared --disable-libssp --disable-libmudflap --enable-checking=yes --enable-languages=c,c++,fortran --with-gmp=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-mpfr=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-mpc=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-isl=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --enable-fix-cortex-a53-843419
libexpat_configure=--prefix=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --without-docbook --without-xmlwf
gdb_configure=--enable-64-bit-bfd --enable-targets=arm-none-eabi,aarch64_be-none-linux-gnu,aarch64_be-none-elf,aarch64-none-linux-gnu,aarch64-none-linux-gnu_ilp32,aarch64-none-elf --target=aarch64-none-linux-gnu --with-bugurl="https://bugs.linaro.org/" --enable-initfini-array --enable-plugins --enable-tui --disable-binutils --disable-sim --disable-as --disable-ld --disable-doc --disable-gdbtk --disable-nls --disable-werror --without-x --prefix= --with-build-sysroot=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/install//aarch64-none-linux-gnu/libc --with-sysroot=/aarch64-none-linux-gnu/libc --with-mpfr --with-libmpfr-prefix=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-libmpfr-type=static --with-libgmp-prefix=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-libgmp-type=static --with-expat --with-libexpat-prefix=/data/jenkins/workspace/GNU-toolchain/arm-10/build-aarch64-none-linux-gnu/host-tools --with-python=yes
gdbserver_configure= --target=aarch64-none-linux-gnu --host=aarch64-none-linux-gnu --program-prefix= --prefix=/usr

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,40 @@
// Low-level type for atomic operations -*- C++ -*-
// Copyright (C) 2004-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file atomic_word.h
* This file is a GNU extension to the Standard C++ Library.
*/
#ifndef _GLIBCXX_ATOMIC_WORD_H
#define _GLIBCXX_ATOMIC_WORD_H 1
typedef int _Atomic_word;
// This is a memory order acquire fence.
#define _GLIBCXX_READ_MEM_BARRIER __atomic_thread_fence (__ATOMIC_ACQUIRE)
// This is a memory order release fence.
#define _GLIBCXX_WRITE_MEM_BARRIER __atomic_thread_fence (__ATOMIC_RELEASE)
#endif

View File

@ -0,0 +1,135 @@
// Wrapper of C-language FILE struct -*- C++ -*-
// Copyright (C) 2000-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
//
// ISO C++ 14882: 27.8 File-based streams
//
/** @file bits/basic_file.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
#ifndef _GLIBCXX_BASIC_FILE_STDIO_H
#define _GLIBCXX_BASIC_FILE_STDIO_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/c++io.h> // for __c_lock and __c_file
#include <bits/move.h> // for swap
#include <ios>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Generic declaration.
template<typename _CharT>
class __basic_file;
// Specialization.
template<>
class __basic_file<char>
{
// Underlying data source/sink.
__c_file* _M_cfile;
// True iff we opened _M_cfile, and thus must close it ourselves.
bool _M_cfile_created;
public:
__basic_file(__c_lock* __lock = 0) throw ();
#if __cplusplus >= 201103L
__basic_file(__basic_file&& __rv, __c_lock* = 0) noexcept
: _M_cfile(__rv._M_cfile), _M_cfile_created(__rv._M_cfile_created)
{
__rv._M_cfile = nullptr;
__rv._M_cfile_created = false;
}
__basic_file& operator=(const __basic_file&) = delete;
__basic_file& operator=(__basic_file&&) = delete;
void
swap(__basic_file& __f) noexcept
{
std::swap(_M_cfile, __f._M_cfile);
std::swap(_M_cfile_created, __f._M_cfile_created);
}
#endif
__basic_file*
open(const char* __name, ios_base::openmode __mode, int __prot = 0664);
#if _GLIBCXX_HAVE__WFOPEN && _GLIBCXX_USE_WCHAR_T
__basic_file*
open(const wchar_t* __name, ios_base::openmode __mode);
#endif
__basic_file*
sys_open(__c_file* __file, ios_base::openmode);
__basic_file*
sys_open(int __fd, ios_base::openmode __mode) throw ();
__basic_file*
close();
_GLIBCXX_PURE bool
is_open() const throw ();
_GLIBCXX_PURE int
fd() throw ();
_GLIBCXX_PURE __c_file*
file() throw ();
~__basic_file();
streamsize
xsputn(const char* __s, streamsize __n);
streamsize
xsputn_2(const char* __s1, streamsize __n1,
const char* __s2, streamsize __n2);
streamsize
xsgetn(char* __s, streamsize __n);
streamoff
seekoff(streamoff __off, ios_base::seekdir __way) throw ();
int
sync();
streamsize
showmanyc();
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,59 @@
// Base to std::allocator -*- C++ -*-
// Copyright (C) 2004-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++allocator.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _GLIBCXX_CXX_ALLOCATOR_H
#define _GLIBCXX_CXX_ALLOCATOR_H 1
#include <ext/new_allocator.h>
#if __cplusplus >= 201103L
namespace std
{
/**
* @brief An alias to the base class for std::allocator.
*
* Used to set the std::allocator base class to
* __gnu_cxx::new_allocator.
*
* @ingroup allocators
* @tparam _Tp Type of allocated object.
*/
template<typename _Tp>
using __allocator_base = __gnu_cxx::new_allocator<_Tp>;
}
#else
// Define new_allocator as the base class to std::allocator.
# define __allocator_base __gnu_cxx::new_allocator
#endif
#if defined(__SANITIZE_ADDRESS__) && !defined(_GLIBCXX_SANITIZE_STD_ALLOCATOR)
# define _GLIBCXX_SANITIZE_STD_ALLOCATOR 1
#endif
#endif

View File

@ -0,0 +1,50 @@
// Underlying io library details -*- C++ -*-
// Copyright (C) 2000-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++io.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
// c_io_stdio.h - Defines for using "C" stdio.h
#ifndef _GLIBCXX_CXX_IO_H
#define _GLIBCXX_CXX_IO_H 1
#include <cstdio>
#include <bits/gthr.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __gthread_mutex_t __c_lock;
// for basic_file.h
typedef FILE __c_file;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,114 @@
// Wrapper for underlying C-language localization -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++locale.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.8 Standard locale categories.
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#ifndef _GLIBCXX_CXX_LOCALE_H
#define _GLIBCXX_CXX_LOCALE_H 1
#pragma GCC system_header
#include <clocale>
#define _GLIBCXX_C_LOCALE_GNU 1
#define _GLIBCXX_NUM_CATEGORIES 6
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
extern "C" __typeof(uselocale) __uselocale;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef __locale_t __c_locale;
// Convert numeric value of type double and long double to string and
// return length of string. If vsnprintf is available use it, otherwise
// fall back to the unsafe vsprintf which, in general, can be dangerous
// and should be avoided.
inline int
__convert_from_v(const __c_locale& __cloc __attribute__ ((__unused__)),
char* __out,
const int __size __attribute__ ((__unused__)),
const char* __fmt, ...)
{
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
__c_locale __old = __gnu_cxx::__uselocale(__cloc);
#else
char* __old = std::setlocale(LC_NUMERIC, 0);
char* __sav = 0;
if (__builtin_strcmp(__old, "C"))
{
const size_t __len = __builtin_strlen(__old) + 1;
__sav = new char[__len];
__builtin_memcpy(__sav, __old, __len);
std::setlocale(LC_NUMERIC, "C");
}
#endif
__builtin_va_list __args;
__builtin_va_start(__args, __fmt);
#if _GLIBCXX_USE_C99_STDIO
const int __ret = __builtin_vsnprintf(__out, __size, __fmt, __args);
#else
const int __ret = __builtin_vsprintf(__out, __fmt, __args);
#endif
__builtin_va_end(__args);
#if __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2)
__gnu_cxx::__uselocale(__old);
#else
if (__sav)
{
std::setlocale(LC_NUMERIC, __sav);
delete [] __sav;
}
#endif
return __ret;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,33 @@
// Specific definitions for generic platforms -*- C++ -*-
// Copyright (C) 2005-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cpu_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _GLIBCXX_CPU_DEFINES
#define _GLIBCXX_CPU_DEFINES 1
#endif

View File

@ -0,0 +1,66 @@
// Locale support -*- C++ -*-
// Copyright (C) 1997-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ctype_base.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.1 Locales
//
// Information as gleaned from /usr/include/ctype.h
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// @brief Base class for ctype.
struct ctype_base
{
// Non-standard typedefs.
typedef const int* __to_type;
// NB: Offsets into ctype<char>::_M_table force a particular size
// on the mask type. Because of this, we don't use an enum.
typedef unsigned short mask;
static const mask upper = _ISupper;
static const mask lower = _ISlower;
static const mask alpha = _ISalpha;
static const mask digit = _ISdigit;
static const mask xdigit = _ISxdigit;
static const mask space = _ISspace;
static const mask print = _ISprint;
static const mask graph = _ISalpha | _ISdigit | _ISpunct;
static const mask cntrl = _IScntrl;
static const mask punct = _ISpunct;
static const mask alnum = _ISalpha | _ISdigit;
#if __cplusplus >= 201103L
static const mask blank = _ISblank;
#endif
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

View File

@ -0,0 +1,76 @@
// Locale support -*- C++ -*-
// Copyright (C) 2000-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/ctype_inline.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.1 Locales
//
// ctype bits to be inlined go here. Non-inlinable (ie virtual do_*)
// functions go in ctype.cc
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
ctype<char>::
is(mask __m, char __c) const
{ return _M_table[static_cast<unsigned char>(__c)] & __m; }
const char*
ctype<char>::
is(const char* __low, const char* __high, mask* __vec) const
{
while (__low < __high)
*__vec++ = _M_table[static_cast<unsigned char>(*__low++)];
return __high;
}
const char*
ctype<char>::
scan_is(mask __m, const char* __low, const char* __high) const
{
while (__low < __high
&& !(_M_table[static_cast<unsigned char>(*__low)] & __m))
++__low;
return __low;
}
const char*
ctype<char>::
scan_not(mask __m, const char* __low, const char* __high) const
{
while (__low < __high
&& (_M_table[static_cast<unsigned char>(*__low)] & __m) != 0)
++__low;
return __low;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

View File

@ -0,0 +1,59 @@
// Control various target specific ABI tweaks. Generic version.
// Copyright (C) 2004-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_tweaks.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{cxxabi.h}
*/
#ifndef _CXXABI_TWEAKS_H
#define _CXXABI_TWEAKS_H 1
#ifdef __cplusplus
namespace __cxxabiv1
{
extern "C"
{
#endif
// The generic ABI uses the first byte of a 64-bit guard variable.
#define _GLIBCXX_GUARD_TEST(x) (*(char *) (x) != 0)
#define _GLIBCXX_GUARD_SET(x) *(char *) (x) = 1
#define _GLIBCXX_GUARD_BIT __guard_test_bit (0, 1)
#define _GLIBCXX_GUARD_PENDING_BIT __guard_test_bit (1, 1)
#define _GLIBCXX_GUARD_WAITING_BIT __guard_test_bit (2, 1)
__extension__ typedef int __guard __attribute__((mode (__DI__)));
// __cxa_vec_ctor has void return type.
typedef void __cxa_vec_ctor_return_type;
#define _GLIBCXX_CXA_VEC_CTOR_RETURN(x) return
// Constructors and destructors do not return a value.
typedef void __cxa_cdtor_return_type;
#ifdef __cplusplus
}
} // namespace __cxxabiv1
#endif
#endif

View File

@ -0,0 +1,178 @@
// Specific definitions for generic platforms -*- C++ -*-
// Copyright (C) 2007-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/error_constants.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{system_error}
*/
#ifndef _GLIBCXX_ERROR_CONSTANTS
#define _GLIBCXX_ERROR_CONSTANTS 1
#include <bits/c++config.h>
#include <cerrno>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
enum class errc
{
address_family_not_supported = EAFNOSUPPORT,
address_in_use = EADDRINUSE,
address_not_available = EADDRNOTAVAIL,
already_connected = EISCONN,
argument_list_too_long = E2BIG,
argument_out_of_domain = EDOM,
bad_address = EFAULT,
bad_file_descriptor = EBADF,
#ifdef EBADMSG
bad_message = EBADMSG,
#endif
broken_pipe = EPIPE,
connection_aborted = ECONNABORTED,
connection_already_in_progress = EALREADY,
connection_refused = ECONNREFUSED,
connection_reset = ECONNRESET,
cross_device_link = EXDEV,
destination_address_required = EDESTADDRREQ,
device_or_resource_busy = EBUSY,
directory_not_empty = ENOTEMPTY,
executable_format_error = ENOEXEC,
file_exists = EEXIST,
file_too_large = EFBIG,
filename_too_long = ENAMETOOLONG,
function_not_supported = ENOSYS,
host_unreachable = EHOSTUNREACH,
#ifdef EIDRM
identifier_removed = EIDRM,
#endif
illegal_byte_sequence = EILSEQ,
inappropriate_io_control_operation = ENOTTY,
interrupted = EINTR,
invalid_argument = EINVAL,
invalid_seek = ESPIPE,
io_error = EIO,
is_a_directory = EISDIR,
message_size = EMSGSIZE,
network_down = ENETDOWN,
network_reset = ENETRESET,
network_unreachable = ENETUNREACH,
no_buffer_space = ENOBUFS,
no_child_process = ECHILD,
#ifdef ENOLINK
no_link = ENOLINK,
#endif
no_lock_available = ENOLCK,
#ifdef ENODATA
no_message_available = ENODATA,
#endif
no_message = ENOMSG,
no_protocol_option = ENOPROTOOPT,
no_space_on_device = ENOSPC,
#ifdef ENOSR
no_stream_resources = ENOSR,
#endif
no_such_device_or_address = ENXIO,
no_such_device = ENODEV,
no_such_file_or_directory = ENOENT,
no_such_process = ESRCH,
not_a_directory = ENOTDIR,
not_a_socket = ENOTSOCK,
#ifdef ENOSTR
not_a_stream = ENOSTR,
#endif
not_connected = ENOTCONN,
not_enough_memory = ENOMEM,
#ifdef ENOTSUP
not_supported = ENOTSUP,
#endif
#ifdef ECANCELED
operation_canceled = ECANCELED,
#endif
operation_in_progress = EINPROGRESS,
operation_not_permitted = EPERM,
operation_not_supported = EOPNOTSUPP,
operation_would_block = EWOULDBLOCK,
#ifdef EOWNERDEAD
owner_dead = EOWNERDEAD,
#endif
permission_denied = EACCES,
#ifdef EPROTO
protocol_error = EPROTO,
#endif
protocol_not_supported = EPROTONOSUPPORT,
read_only_file_system = EROFS,
resource_deadlock_would_occur = EDEADLK,
resource_unavailable_try_again = EAGAIN,
result_out_of_range = ERANGE,
#ifdef ENOTRECOVERABLE
state_not_recoverable = ENOTRECOVERABLE,
#endif
#ifdef ETIME
stream_timeout = ETIME,
#endif
#ifdef ETXTBSY
text_file_busy = ETXTBSY,
#endif
timed_out = ETIMEDOUT,
too_many_files_open_in_system = ENFILE,
too_many_files_open = EMFILE,
too_many_links = EMLINK,
too_many_symbolic_link_levels = ELOOP,
#ifdef EOVERFLOW
value_too_large = EOVERFLOW,
#endif
wrong_protocol_type = EPROTOTYPE
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,83 @@
// C++ includes used for precompiling extensions -*- C++ -*-
// Copyright (C) 2006-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file extc++.h
* This is an implementation file for a precompiled header.
*/
#if __cplusplus < 201103L
#include <bits/stdtr1c++.h>
#else
#include <bits/stdc++.h>
#endif
#include <ext/algorithm>
#if __cplusplus >= 201103L
# include <ext/aligned_buffer.h>
#endif
#include <ext/alloc_traits.h>
#include <ext/atomicity.h>
#include <ext/bitmap_allocator.h>
#include <ext/cast.h>
#if __cplusplus >= 201103L
# include <ext/cmath>
#endif
#include <ext/concurrence.h>
#include <ext/debug_allocator.h>
#include <ext/extptr_allocator.h>
#include <ext/functional>
#include <ext/iterator>
#include <ext/malloc_allocator.h>
#include <ext/memory>
#include <ext/mt_allocator.h>
#include <ext/new_allocator.h>
#include <ext/numeric>
#include <ext/numeric_traits.h>
#include <ext/pod_char_traits.h>
#include <ext/pointer.h>
#include <ext/pool_allocator.h>
#if __cplusplus >= 201103L
# include <ext/random>
#endif
#include <ext/rb_tree>
#include <ext/rope>
#include <ext/slist>
#include <ext/stdio_filebuf.h>
#include <ext/stdio_sync_filebuf.h>
#include <ext/throw_allocator.h>
#include <ext/typelist.h>
#include <ext/type_traits.h>
#include <ext/vstring.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/exception.hpp>
#include <ext/pb_ds/hash_policy.hpp>
#include <ext/pb_ds/list_update_policy.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/trie_policy.hpp>
#ifdef _GLIBCXX_HAVE_ICONV
#include <ext/codecvt_specializations.h>
#include <ext/enc_filebuf.h>
#endif

View File

@ -0,0 +1,890 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GLIBCXX_GCC_GTHR_POSIX_H
#define _GLIBCXX_GCC_GTHR_POSIX_H
/* POSIX threads specific definitions.
Easy, since the interface is just one-to-one mapping. */
#define __GTHREADS 1
#define __GTHREADS_CXX0X 1
#include <pthread.h>
#if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \
|| !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK))
# include <unistd.h>
# if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0
# define _GTHREAD_USE_MUTEX_TIMEDLOCK 1
# else
# define _GTHREAD_USE_MUTEX_TIMEDLOCK 0
# endif
#endif
typedef pthread_t __gthread_t;
typedef pthread_key_t __gthread_key_t;
typedef pthread_once_t __gthread_once_t;
typedef pthread_mutex_t __gthread_mutex_t;
typedef pthread_mutex_t __gthread_recursive_mutex_t;
typedef pthread_cond_t __gthread_cond_t;
typedef struct timespec __gthread_time_t;
/* POSIX like conditional variables are supported. Please look at comments
in gthr.h for details. */
#define __GTHREAD_HAS_COND 1
#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#else
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
#endif
#define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
#define __GTHREAD_TIME_INIT {0,0}
#ifdef _GTHREAD_USE_MUTEX_INIT_FUNC
# undef __GTHREAD_MUTEX_INIT
#endif
#ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
# undef __GTHREAD_RECURSIVE_MUTEX_INIT
# undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
# define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
#endif
#ifdef _GTHREAD_USE_COND_INIT_FUNC
# undef __GTHREAD_COND_INIT
# define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function
#endif
#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
# ifndef __gthrw_pragma
# define __gthrw_pragma(pragma)
# endif
# define __gthrw2(name,name2,type) \
static __typeof(type) name \
__attribute__ ((__weakref__(#name2), __copy__ (type))); \
__gthrw_pragma(weak type)
# define __gthrw_(name) __gthrw_ ## name
#else
# define __gthrw2(name,name2,type)
# define __gthrw_(name) name
#endif
/* Typically, __gthrw_foo is a weak reference to symbol foo. */
#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
__gthrw(pthread_once)
__gthrw(pthread_getspecific)
__gthrw(pthread_setspecific)
__gthrw(pthread_create)
__gthrw(pthread_join)
__gthrw(pthread_equal)
__gthrw(pthread_self)
__gthrw(pthread_detach)
#ifndef __BIONIC__
__gthrw(pthread_cancel)
#endif
__gthrw(sched_yield)
__gthrw(pthread_mutex_lock)
__gthrw(pthread_mutex_trylock)
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
__gthrw(pthread_mutex_timedlock)
#endif
__gthrw(pthread_mutex_unlock)
__gthrw(pthread_mutex_init)
__gthrw(pthread_mutex_destroy)
__gthrw(pthread_cond_init)
__gthrw(pthread_cond_broadcast)
__gthrw(pthread_cond_signal)
__gthrw(pthread_cond_wait)
__gthrw(pthread_cond_timedwait)
__gthrw(pthread_cond_destroy)
__gthrw(pthread_key_create)
__gthrw(pthread_key_delete)
__gthrw(pthread_mutexattr_init)
__gthrw(pthread_mutexattr_settype)
__gthrw(pthread_mutexattr_destroy)
#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
/* Objective-C. */
__gthrw(pthread_exit)
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
__gthrw(sched_get_priority_max)
__gthrw(sched_get_priority_min)
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _POSIX_PRIORITY_SCHEDULING */
__gthrw(pthread_attr_destroy)
__gthrw(pthread_attr_init)
__gthrw(pthread_attr_setdetachstate)
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
__gthrw(pthread_getschedparam)
__gthrw(pthread_setschedparam)
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _LIBOBJC || _LIBOBJC_WEAK */
#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
-pthreads is not specified. The functions are dummies and most return an
error value. However pthread_once returns 0 without invoking the routine
it is passed so we cannot pretend that the interface is active if -pthreads
is not specified. On Solaris 2.5.1, the interface is not exposed at all so
we need to play the usual game with weak symbols. On Solaris 10 and up, a
working interface is always exposed. On FreeBSD 6 and later, libc also
exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
which means the alternate __gthread_active_p below cannot be used there. */
#if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
static volatile int __gthread_active = -1;
static void
__gthread_trigger (void)
{
__gthread_active = 1;
}
static inline int
__gthread_active_p (void)
{
static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
/* Avoid reading __gthread_active twice on the main code path. */
int __gthread_active_latest_value = __gthread_active;
/* This test is not protected to avoid taking a lock on the main code
path so every update of __gthread_active in a threaded program must
be atomic with regard to the result of the test. */
if (__builtin_expect (__gthread_active_latest_value < 0, 0))
{
if (__gthrw_(pthread_once))
{
/* If this really is a threaded program, then we must ensure that
__gthread_active has been set to 1 before exiting this block. */
__gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
__gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
__gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
}
/* Make sure we'll never enter this block again. */
if (__gthread_active < 0)
__gthread_active = 0;
__gthread_active_latest_value = __gthread_active;
}
return __gthread_active_latest_value != 0;
}
#else /* neither FreeBSD nor Solaris */
/* For a program to be multi-threaded the only thing that it certainly must
be using is pthread_create. However, there may be other libraries that
intercept pthread_create with their own definitions to wrap pthreads
functionality for some purpose. In those cases, pthread_create being
defined might not necessarily mean that libpthread is actually linked
in.
For the GNU C library, we can use a known internal name. This is always
available in the ABI, but no other library would define it. That is
ideal, since any public pthread function might be intercepted just as
pthread_create might be. __pthread_key_create is an "internal"
implementation symbol, but it is part of the public exported ABI. Also,
it's among the symbols that the static libpthread.a always links in
whenever pthread_create is used, so there is no danger of a false
negative result in any statically-linked, multi-threaded program.
For others, we choose pthread_cancel as a function that seems unlikely
to be redefined by an interceptor library. The bionic (Android) C
library does not provide pthread_cancel, so we do use pthread_create
there (and interceptor libraries lose). */
#ifdef __GLIBC__
__gthrw2(__gthrw_(__pthread_key_create),
__pthread_key_create,
pthread_key_create)
# define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create)
#elif defined (__BIONIC__)
# define GTHR_ACTIVE_PROXY __gthrw_(pthread_create)
#else
# define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel)
#endif
static inline int
__gthread_active_p (void)
{
static void *const __gthread_active_ptr
= __extension__ (void *) &GTHR_ACTIVE_PROXY;
return __gthread_active_ptr != 0;
}
#endif /* FreeBSD or Solaris */
#else /* not __GXX_WEAK__ */
/* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
calls in shared flavors of the HP-UX C library. Most of the stubs
have no functionality. The details are described in the "libc cumulative
patch" for each subversion of HP-UX 11. There are two special interfaces
provided for checking whether an application is linked to a shared pthread
library or not. However, these interfaces aren't available in early
libpthread libraries. We also need a test that works for archive
libraries. We can't use pthread_once as some libc versions call the
init function. We also can't use pthread_create or pthread_attr_init
as these create a thread and thereby prevent changing the default stack
size. The function pthread_default_stacksize_np is available in both
the archive and shared versions of libpthread. It can be used to
determine the default pthread stack size. There is a stub in some
shared libc versions which returns a zero size if pthreads are not
active. We provide an equivalent stub to handle cases where libc
doesn't provide one. */
#if defined(__hppa__) && defined(__hpux__)
static volatile int __gthread_active = -1;
static inline int
__gthread_active_p (void)
{
/* Avoid reading __gthread_active twice on the main code path. */
int __gthread_active_latest_value = __gthread_active;
size_t __s;
if (__builtin_expect (__gthread_active_latest_value < 0, 0))
{
pthread_default_stacksize_np (0, &__s);
__gthread_active = __s ? 1 : 0;
__gthread_active_latest_value = __gthread_active;
}
return __gthread_active_latest_value != 0;
}
#else /* not hppa-hpux */
static inline int
__gthread_active_p (void)
{
return 1;
}
#endif /* hppa-hpux */
#endif /* __GXX_WEAK__ */
#ifdef _LIBOBJC
/* This is the config.h file in libobjc/ */
#include <config.h>
#ifdef HAVE_SCHED_H
# include <sched.h>
#endif
/* Key structure for maintaining thread specific storage */
static pthread_key_t _objc_thread_storage;
static pthread_attr_t _objc_thread_attribs;
/* Thread local storage for a single thread */
static void *thread_local_storage = NULL;
/* Backend initialization functions */
/* Initialize the threads subsystem. */
static inline int
__gthread_objc_init_thread_system (void)
{
if (__gthread_active_p ())
{
/* Initialize the thread storage key. */
if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
{
/* The normal default detach state for threads is
* PTHREAD_CREATE_JOINABLE which causes threads to not die
* when you think they should. */
if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
&& __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
PTHREAD_CREATE_DETACHED) == 0)
return 0;
}
}
return -1;
}
/* Close the threads subsystem. */
static inline int
__gthread_objc_close_thread_system (void)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
&& __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
return 0;
return -1;
}
/* Backend thread functions */
/* Create a new thread of execution. */
static inline objc_thread_t
__gthread_objc_thread_detach (void (*func)(void *), void *arg)
{
objc_thread_t thread_id;
pthread_t new_thread_handle;
if (!__gthread_active_p ())
return NULL;
if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs,
(void *) func, arg)))
thread_id = (objc_thread_t) new_thread_handle;
else
thread_id = NULL;
return thread_id;
}
/* Set the current thread's priority. */
static inline int
__gthread_objc_thread_set_priority (int priority)
{
if (!__gthread_active_p ())
return -1;
else
{
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
pthread_t thread_id = __gthrw_(pthread_self) ();
int policy;
struct sched_param params;
int priority_min, priority_max;
if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
{
if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
return -1;
if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
return -1;
if (priority > priority_max)
priority = priority_max;
else if (priority < priority_min)
priority = priority_min;
params.sched_priority = priority;
/*
* The solaris 7 and several other man pages incorrectly state that
* this should be a pointer to policy but pthread.h is universally
* at odds with this.
*/
if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
return 0;
}
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _POSIX_PRIORITY_SCHEDULING */
return -1;
}
}
/* Return the current thread's priority. */
static inline int
__gthread_objc_thread_get_priority (void)
{
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
if (__gthread_active_p ())
{
int policy;
struct sched_param params;
if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
return params.sched_priority;
else
return -1;
}
else
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _POSIX_PRIORITY_SCHEDULING */
return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
/* Yield our process time to another thread. */
static inline void
__gthread_objc_thread_yield (void)
{
if (__gthread_active_p ())
__gthrw_(sched_yield) ();
}
/* Terminate the current thread. */
static inline int
__gthread_objc_thread_exit (void)
{
if (__gthread_active_p ())
/* exit the thread */
__gthrw_(pthread_exit) (&__objc_thread_exit_status);
/* Failed if we reached here */
return -1;
}
/* Returns an integer value which uniquely describes a thread. */
static inline objc_thread_t
__gthread_objc_thread_id (void)
{
if (__gthread_active_p ())
return (objc_thread_t) __gthrw_(pthread_self) ();
else
return (objc_thread_t) 1;
}
/* Sets the thread's local storage pointer. */
static inline int
__gthread_objc_thread_set_data (void *value)
{
if (__gthread_active_p ())
return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
else
{
thread_local_storage = value;
return 0;
}
}
/* Returns the thread's local storage pointer. */
static inline void *
__gthread_objc_thread_get_data (void)
{
if (__gthread_active_p ())
return __gthrw_(pthread_getspecific) (_objc_thread_storage);
else
return thread_local_storage;
}
/* Backend mutex functions */
/* Allocate a mutex. */
static inline int
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
{
if (__gthread_active_p ())
{
mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
{
objc_free (mutex->backend);
mutex->backend = NULL;
return -1;
}
}
return 0;
}
/* Deallocate a mutex. */
static inline int
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
{
if (__gthread_active_p ())
{
int count;
/*
* Posix Threads specifically require that the thread be unlocked
* for __gthrw_(pthread_mutex_destroy) to work.
*/
do
{
count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
if (count < 0)
return -1;
}
while (count);
if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
return -1;
objc_free (mutex->backend);
mutex->backend = NULL;
}
return 0;
}
/* Grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_lock (objc_mutex_t mutex)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
{
return -1;
}
return 0;
}
/* Try to grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_trylock (objc_mutex_t mutex)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
{
return -1;
}
return 0;
}
/* Unlock the mutex */
static inline int
__gthread_objc_mutex_unlock (objc_mutex_t mutex)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
{
return -1;
}
return 0;
}
/* Backend condition mutex functions */
/* Allocate a condition. */
static inline int
__gthread_objc_condition_allocate (objc_condition_t condition)
{
if (__gthread_active_p ())
{
condition->backend = objc_malloc (sizeof (pthread_cond_t));
if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
{
objc_free (condition->backend);
condition->backend = NULL;
return -1;
}
}
return 0;
}
/* Deallocate a condition. */
static inline int
__gthread_objc_condition_deallocate (objc_condition_t condition)
{
if (__gthread_active_p ())
{
if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
return -1;
objc_free (condition->backend);
condition->backend = NULL;
}
return 0;
}
/* Wait on the condition */
static inline int
__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
(pthread_mutex_t *) mutex->backend);
else
return 0;
}
/* Wake up all threads waiting on this condition. */
static inline int
__gthread_objc_condition_broadcast (objc_condition_t condition)
{
if (__gthread_active_p ())
return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
else
return 0;
}
/* Wake up one thread waiting on this condition. */
static inline int
__gthread_objc_condition_signal (objc_condition_t condition)
{
if (__gthread_active_p ())
return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
else
return 0;
}
#else /* _LIBOBJC */
static inline int
__gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
void *__args)
{
return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
}
static inline int
__gthread_join (__gthread_t __threadid, void **__value_ptr)
{
return __gthrw_(pthread_join) (__threadid, __value_ptr);
}
static inline int
__gthread_detach (__gthread_t __threadid)
{
return __gthrw_(pthread_detach) (__threadid);
}
static inline int
__gthread_equal (__gthread_t __t1, __gthread_t __t2)
{
return __gthrw_(pthread_equal) (__t1, __t2);
}
static inline __gthread_t
__gthread_self (void)
{
return __gthrw_(pthread_self) ();
}
static inline int
__gthread_yield (void)
{
return __gthrw_(sched_yield) ();
}
static inline int
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
{
if (__gthread_active_p ())
return __gthrw_(pthread_once) (__once, __func);
else
return -1;
}
static inline int
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
{
return __gthrw_(pthread_key_create) (__key, __dtor);
}
static inline int
__gthread_key_delete (__gthread_key_t __key)
{
return __gthrw_(pthread_key_delete) (__key);
}
static inline void *
__gthread_getspecific (__gthread_key_t __key)
{
return __gthrw_(pthread_getspecific) (__key);
}
static inline int
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
{
return __gthrw_(pthread_setspecific) (__key, __ptr);
}
static inline void
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
__gthrw_(pthread_mutex_init) (__mutex, NULL);
}
static inline int
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_destroy) (__mutex);
else
return 0;
}
static inline int
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_lock) (__mutex);
else
return 0;
}
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_trylock) (__mutex);
else
return 0;
}
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
static inline int
__gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
const __gthread_time_t *__abs_timeout)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
else
return 0;
}
#endif
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_unlock) (__mutex);
else
return 0;
}
#if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \
|| defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC)
static inline int
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
{
if (__gthread_active_p ())
{
pthread_mutexattr_t __attr;
int __r;
__r = __gthrw_(pthread_mutexattr_init) (&__attr);
if (!__r)
__r = __gthrw_(pthread_mutexattr_settype) (&__attr,
PTHREAD_MUTEX_RECURSIVE);
if (!__r)
__r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
if (!__r)
__r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
return __r;
}
return 0;
}
#endif
static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_lock (__mutex);
}
static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_trylock (__mutex);
}
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
static inline int
__gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
const __gthread_time_t *__abs_timeout)
{
return __gthread_mutex_timedlock (__mutex, __abs_timeout);
}
#endif
static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_unlock (__mutex);
}
static inline int
__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_destroy (__mutex);
}
#ifdef _GTHREAD_USE_COND_INIT_FUNC
static inline void
__gthread_cond_init_function (__gthread_cond_t *__cond)
{
if (__gthread_active_p ())
__gthrw_(pthread_cond_init) (__cond, NULL);
}
#endif
static inline int
__gthread_cond_broadcast (__gthread_cond_t *__cond)
{
return __gthrw_(pthread_cond_broadcast) (__cond);
}
static inline int
__gthread_cond_signal (__gthread_cond_t *__cond)
{
return __gthrw_(pthread_cond_signal) (__cond);
}
static inline int
__gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
{
return __gthrw_(pthread_cond_wait) (__cond, __mutex);
}
static inline int
__gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
const __gthread_time_t *__abs_timeout)
{
return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
}
static inline int
__gthread_cond_wait_recursive (__gthread_cond_t *__cond,
__gthread_recursive_mutex_t *__mutex)
{
return __gthread_cond_wait (__cond, __mutex);
}
static inline int
__gthread_cond_destroy (__gthread_cond_t* __cond)
{
return __gthrw_(pthread_cond_destroy) (__cond);
}
#endif /* _LIBOBJC */
#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */

View File

@ -0,0 +1,890 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GLIBCXX_GCC_GTHR_POSIX_H
#define _GLIBCXX_GCC_GTHR_POSIX_H
/* POSIX threads specific definitions.
Easy, since the interface is just one-to-one mapping. */
#define __GTHREADS 1
#define __GTHREADS_CXX0X 1
#include <pthread.h>
#if ((defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)) \
|| !defined(_GTHREAD_USE_MUTEX_TIMEDLOCK))
# include <unistd.h>
# if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 0
# define _GTHREAD_USE_MUTEX_TIMEDLOCK 1
# else
# define _GTHREAD_USE_MUTEX_TIMEDLOCK 0
# endif
#endif
typedef pthread_t __gthread_t;
typedef pthread_key_t __gthread_key_t;
typedef pthread_once_t __gthread_once_t;
typedef pthread_mutex_t __gthread_mutex_t;
typedef pthread_mutex_t __gthread_recursive_mutex_t;
typedef pthread_cond_t __gthread_cond_t;
typedef struct timespec __gthread_time_t;
/* POSIX like conditional variables are supported. Please look at comments
in gthr.h for details. */
#define __GTHREAD_HAS_COND 1
#define __GTHREAD_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
#define __GTHREAD_MUTEX_INIT_FUNCTION __gthread_mutex_init_function
#define __GTHREAD_ONCE_INIT PTHREAD_ONCE_INIT
#if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
#define __GTHREAD_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
#else
#define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
#endif
#define __GTHREAD_COND_INIT PTHREAD_COND_INITIALIZER
#define __GTHREAD_TIME_INIT {0,0}
#ifdef _GTHREAD_USE_MUTEX_INIT_FUNC
# undef __GTHREAD_MUTEX_INIT
#endif
#ifdef _GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC
# undef __GTHREAD_RECURSIVE_MUTEX_INIT
# undef __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
# define __GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION __gthread_recursive_mutex_init_function
#endif
#ifdef _GTHREAD_USE_COND_INIT_FUNC
# undef __GTHREAD_COND_INIT
# define __GTHREAD_COND_INIT_FUNCTION __gthread_cond_init_function
#endif
#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
# ifndef __gthrw_pragma
# define __gthrw_pragma(pragma)
# endif
# define __gthrw2(name,name2,type) \
static __typeof(type) name \
__attribute__ ((__weakref__(#name2), __copy__ (type))); \
__gthrw_pragma(weak type)
# define __gthrw_(name) __gthrw_ ## name
#else
# define __gthrw2(name,name2,type)
# define __gthrw_(name) name
#endif
/* Typically, __gthrw_foo is a weak reference to symbol foo. */
#define __gthrw(name) __gthrw2(__gthrw_ ## name,name,name)
__gthrw(pthread_once)
__gthrw(pthread_getspecific)
__gthrw(pthread_setspecific)
__gthrw(pthread_create)
__gthrw(pthread_join)
__gthrw(pthread_equal)
__gthrw(pthread_self)
__gthrw(pthread_detach)
#ifndef __BIONIC__
__gthrw(pthread_cancel)
#endif
__gthrw(sched_yield)
__gthrw(pthread_mutex_lock)
__gthrw(pthread_mutex_trylock)
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
__gthrw(pthread_mutex_timedlock)
#endif
__gthrw(pthread_mutex_unlock)
__gthrw(pthread_mutex_init)
__gthrw(pthread_mutex_destroy)
__gthrw(pthread_cond_init)
__gthrw(pthread_cond_broadcast)
__gthrw(pthread_cond_signal)
__gthrw(pthread_cond_wait)
__gthrw(pthread_cond_timedwait)
__gthrw(pthread_cond_destroy)
__gthrw(pthread_key_create)
__gthrw(pthread_key_delete)
__gthrw(pthread_mutexattr_init)
__gthrw(pthread_mutexattr_settype)
__gthrw(pthread_mutexattr_destroy)
#if defined(_LIBOBJC) || defined(_LIBOBJC_WEAK)
/* Objective-C. */
__gthrw(pthread_exit)
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
__gthrw(sched_get_priority_max)
__gthrw(sched_get_priority_min)
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _POSIX_PRIORITY_SCHEDULING */
__gthrw(pthread_attr_destroy)
__gthrw(pthread_attr_init)
__gthrw(pthread_attr_setdetachstate)
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
__gthrw(pthread_getschedparam)
__gthrw(pthread_setschedparam)
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _LIBOBJC || _LIBOBJC_WEAK */
#if __GXX_WEAK__ && _GLIBCXX_GTHREAD_USE_WEAK
/* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if
-pthreads is not specified. The functions are dummies and most return an
error value. However pthread_once returns 0 without invoking the routine
it is passed so we cannot pretend that the interface is active if -pthreads
is not specified. On Solaris 2.5.1, the interface is not exposed at all so
we need to play the usual game with weak symbols. On Solaris 10 and up, a
working interface is always exposed. On FreeBSD 6 and later, libc also
exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up
to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc,
which means the alternate __gthread_active_p below cannot be used there. */
#if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
static volatile int __gthread_active = -1;
static void
__gthread_trigger (void)
{
__gthread_active = 1;
}
static inline int
__gthread_active_p (void)
{
static pthread_mutex_t __gthread_active_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
/* Avoid reading __gthread_active twice on the main code path. */
int __gthread_active_latest_value = __gthread_active;
/* This test is not protected to avoid taking a lock on the main code
path so every update of __gthread_active in a threaded program must
be atomic with regard to the result of the test. */
if (__builtin_expect (__gthread_active_latest_value < 0, 0))
{
if (__gthrw_(pthread_once))
{
/* If this really is a threaded program, then we must ensure that
__gthread_active has been set to 1 before exiting this block. */
__gthrw_(pthread_mutex_lock) (&__gthread_active_mutex);
__gthrw_(pthread_once) (&__gthread_active_once, __gthread_trigger);
__gthrw_(pthread_mutex_unlock) (&__gthread_active_mutex);
}
/* Make sure we'll never enter this block again. */
if (__gthread_active < 0)
__gthread_active = 0;
__gthread_active_latest_value = __gthread_active;
}
return __gthread_active_latest_value != 0;
}
#else /* neither FreeBSD nor Solaris */
/* For a program to be multi-threaded the only thing that it certainly must
be using is pthread_create. However, there may be other libraries that
intercept pthread_create with their own definitions to wrap pthreads
functionality for some purpose. In those cases, pthread_create being
defined might not necessarily mean that libpthread is actually linked
in.
For the GNU C library, we can use a known internal name. This is always
available in the ABI, but no other library would define it. That is
ideal, since any public pthread function might be intercepted just as
pthread_create might be. __pthread_key_create is an "internal"
implementation symbol, but it is part of the public exported ABI. Also,
it's among the symbols that the static libpthread.a always links in
whenever pthread_create is used, so there is no danger of a false
negative result in any statically-linked, multi-threaded program.
For others, we choose pthread_cancel as a function that seems unlikely
to be redefined by an interceptor library. The bionic (Android) C
library does not provide pthread_cancel, so we do use pthread_create
there (and interceptor libraries lose). */
#ifdef __GLIBC__
__gthrw2(__gthrw_(__pthread_key_create),
__pthread_key_create,
pthread_key_create)
# define GTHR_ACTIVE_PROXY __gthrw_(__pthread_key_create)
#elif defined (__BIONIC__)
# define GTHR_ACTIVE_PROXY __gthrw_(pthread_create)
#else
# define GTHR_ACTIVE_PROXY __gthrw_(pthread_cancel)
#endif
static inline int
__gthread_active_p (void)
{
static void *const __gthread_active_ptr
= __extension__ (void *) &GTHR_ACTIVE_PROXY;
return __gthread_active_ptr != 0;
}
#endif /* FreeBSD or Solaris */
#else /* not __GXX_WEAK__ */
/* Similar to Solaris, HP-UX 11 for PA-RISC provides stubs for pthread
calls in shared flavors of the HP-UX C library. Most of the stubs
have no functionality. The details are described in the "libc cumulative
patch" for each subversion of HP-UX 11. There are two special interfaces
provided for checking whether an application is linked to a shared pthread
library or not. However, these interfaces aren't available in early
libpthread libraries. We also need a test that works for archive
libraries. We can't use pthread_once as some libc versions call the
init function. We also can't use pthread_create or pthread_attr_init
as these create a thread and thereby prevent changing the default stack
size. The function pthread_default_stacksize_np is available in both
the archive and shared versions of libpthread. It can be used to
determine the default pthread stack size. There is a stub in some
shared libc versions which returns a zero size if pthreads are not
active. We provide an equivalent stub to handle cases where libc
doesn't provide one. */
#if defined(__hppa__) && defined(__hpux__)
static volatile int __gthread_active = -1;
static inline int
__gthread_active_p (void)
{
/* Avoid reading __gthread_active twice on the main code path. */
int __gthread_active_latest_value = __gthread_active;
size_t __s;
if (__builtin_expect (__gthread_active_latest_value < 0, 0))
{
pthread_default_stacksize_np (0, &__s);
__gthread_active = __s ? 1 : 0;
__gthread_active_latest_value = __gthread_active;
}
return __gthread_active_latest_value != 0;
}
#else /* not hppa-hpux */
static inline int
__gthread_active_p (void)
{
return 1;
}
#endif /* hppa-hpux */
#endif /* __GXX_WEAK__ */
#ifdef _LIBOBJC
/* This is the config.h file in libobjc/ */
#include <config.h>
#ifdef HAVE_SCHED_H
# include <sched.h>
#endif
/* Key structure for maintaining thread specific storage */
static pthread_key_t _objc_thread_storage;
static pthread_attr_t _objc_thread_attribs;
/* Thread local storage for a single thread */
static void *thread_local_storage = NULL;
/* Backend initialization functions */
/* Initialize the threads subsystem. */
static inline int
__gthread_objc_init_thread_system (void)
{
if (__gthread_active_p ())
{
/* Initialize the thread storage key. */
if (__gthrw_(pthread_key_create) (&_objc_thread_storage, NULL) == 0)
{
/* The normal default detach state for threads is
* PTHREAD_CREATE_JOINABLE which causes threads to not die
* when you think they should. */
if (__gthrw_(pthread_attr_init) (&_objc_thread_attribs) == 0
&& __gthrw_(pthread_attr_setdetachstate) (&_objc_thread_attribs,
PTHREAD_CREATE_DETACHED) == 0)
return 0;
}
}
return -1;
}
/* Close the threads subsystem. */
static inline int
__gthread_objc_close_thread_system (void)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_key_delete) (_objc_thread_storage) == 0
&& __gthrw_(pthread_attr_destroy) (&_objc_thread_attribs) == 0)
return 0;
return -1;
}
/* Backend thread functions */
/* Create a new thread of execution. */
static inline objc_thread_t
__gthread_objc_thread_detach (void (*func)(void *), void *arg)
{
objc_thread_t thread_id;
pthread_t new_thread_handle;
if (!__gthread_active_p ())
return NULL;
if (!(__gthrw_(pthread_create) (&new_thread_handle, &_objc_thread_attribs,
(void *) func, arg)))
thread_id = (objc_thread_t) new_thread_handle;
else
thread_id = NULL;
return thread_id;
}
/* Set the current thread's priority. */
static inline int
__gthread_objc_thread_set_priority (int priority)
{
if (!__gthread_active_p ())
return -1;
else
{
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
pthread_t thread_id = __gthrw_(pthread_self) ();
int policy;
struct sched_param params;
int priority_min, priority_max;
if (__gthrw_(pthread_getschedparam) (thread_id, &policy, &params) == 0)
{
if ((priority_max = __gthrw_(sched_get_priority_max) (policy)) == -1)
return -1;
if ((priority_min = __gthrw_(sched_get_priority_min) (policy)) == -1)
return -1;
if (priority > priority_max)
priority = priority_max;
else if (priority < priority_min)
priority = priority_min;
params.sched_priority = priority;
/*
* The solaris 7 and several other man pages incorrectly state that
* this should be a pointer to policy but pthread.h is universally
* at odds with this.
*/
if (__gthrw_(pthread_setschedparam) (thread_id, policy, &params) == 0)
return 0;
}
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _POSIX_PRIORITY_SCHEDULING */
return -1;
}
}
/* Return the current thread's priority. */
static inline int
__gthread_objc_thread_get_priority (void)
{
#ifdef _POSIX_PRIORITY_SCHEDULING
#ifdef _POSIX_THREAD_PRIORITY_SCHEDULING
if (__gthread_active_p ())
{
int policy;
struct sched_param params;
if (__gthrw_(pthread_getschedparam) (__gthrw_(pthread_self) (), &policy, &params) == 0)
return params.sched_priority;
else
return -1;
}
else
#endif /* _POSIX_THREAD_PRIORITY_SCHEDULING */
#endif /* _POSIX_PRIORITY_SCHEDULING */
return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
/* Yield our process time to another thread. */
static inline void
__gthread_objc_thread_yield (void)
{
if (__gthread_active_p ())
__gthrw_(sched_yield) ();
}
/* Terminate the current thread. */
static inline int
__gthread_objc_thread_exit (void)
{
if (__gthread_active_p ())
/* exit the thread */
__gthrw_(pthread_exit) (&__objc_thread_exit_status);
/* Failed if we reached here */
return -1;
}
/* Returns an integer value which uniquely describes a thread. */
static inline objc_thread_t
__gthread_objc_thread_id (void)
{
if (__gthread_active_p ())
return (objc_thread_t) __gthrw_(pthread_self) ();
else
return (objc_thread_t) 1;
}
/* Sets the thread's local storage pointer. */
static inline int
__gthread_objc_thread_set_data (void *value)
{
if (__gthread_active_p ())
return __gthrw_(pthread_setspecific) (_objc_thread_storage, value);
else
{
thread_local_storage = value;
return 0;
}
}
/* Returns the thread's local storage pointer. */
static inline void *
__gthread_objc_thread_get_data (void)
{
if (__gthread_active_p ())
return __gthrw_(pthread_getspecific) (_objc_thread_storage);
else
return thread_local_storage;
}
/* Backend mutex functions */
/* Allocate a mutex. */
static inline int
__gthread_objc_mutex_allocate (objc_mutex_t mutex)
{
if (__gthread_active_p ())
{
mutex->backend = objc_malloc (sizeof (pthread_mutex_t));
if (__gthrw_(pthread_mutex_init) ((pthread_mutex_t *) mutex->backend, NULL))
{
objc_free (mutex->backend);
mutex->backend = NULL;
return -1;
}
}
return 0;
}
/* Deallocate a mutex. */
static inline int
__gthread_objc_mutex_deallocate (objc_mutex_t mutex)
{
if (__gthread_active_p ())
{
int count;
/*
* Posix Threads specifically require that the thread be unlocked
* for __gthrw_(pthread_mutex_destroy) to work.
*/
do
{
count = __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend);
if (count < 0)
return -1;
}
while (count);
if (__gthrw_(pthread_mutex_destroy) ((pthread_mutex_t *) mutex->backend))
return -1;
objc_free (mutex->backend);
mutex->backend = NULL;
}
return 0;
}
/* Grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_lock (objc_mutex_t mutex)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_mutex_lock) ((pthread_mutex_t *) mutex->backend) != 0)
{
return -1;
}
return 0;
}
/* Try to grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_trylock (objc_mutex_t mutex)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_mutex_trylock) ((pthread_mutex_t *) mutex->backend) != 0)
{
return -1;
}
return 0;
}
/* Unlock the mutex */
static inline int
__gthread_objc_mutex_unlock (objc_mutex_t mutex)
{
if (__gthread_active_p ()
&& __gthrw_(pthread_mutex_unlock) ((pthread_mutex_t *) mutex->backend) != 0)
{
return -1;
}
return 0;
}
/* Backend condition mutex functions */
/* Allocate a condition. */
static inline int
__gthread_objc_condition_allocate (objc_condition_t condition)
{
if (__gthread_active_p ())
{
condition->backend = objc_malloc (sizeof (pthread_cond_t));
if (__gthrw_(pthread_cond_init) ((pthread_cond_t *) condition->backend, NULL))
{
objc_free (condition->backend);
condition->backend = NULL;
return -1;
}
}
return 0;
}
/* Deallocate a condition. */
static inline int
__gthread_objc_condition_deallocate (objc_condition_t condition)
{
if (__gthread_active_p ())
{
if (__gthrw_(pthread_cond_destroy) ((pthread_cond_t *) condition->backend))
return -1;
objc_free (condition->backend);
condition->backend = NULL;
}
return 0;
}
/* Wait on the condition */
static inline int
__gthread_objc_condition_wait (objc_condition_t condition, objc_mutex_t mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_cond_wait) ((pthread_cond_t *) condition->backend,
(pthread_mutex_t *) mutex->backend);
else
return 0;
}
/* Wake up all threads waiting on this condition. */
static inline int
__gthread_objc_condition_broadcast (objc_condition_t condition)
{
if (__gthread_active_p ())
return __gthrw_(pthread_cond_broadcast) ((pthread_cond_t *) condition->backend);
else
return 0;
}
/* Wake up one thread waiting on this condition. */
static inline int
__gthread_objc_condition_signal (objc_condition_t condition)
{
if (__gthread_active_p ())
return __gthrw_(pthread_cond_signal) ((pthread_cond_t *) condition->backend);
else
return 0;
}
#else /* _LIBOBJC */
static inline int
__gthread_create (__gthread_t *__threadid, void *(*__func) (void*),
void *__args)
{
return __gthrw_(pthread_create) (__threadid, NULL, __func, __args);
}
static inline int
__gthread_join (__gthread_t __threadid, void **__value_ptr)
{
return __gthrw_(pthread_join) (__threadid, __value_ptr);
}
static inline int
__gthread_detach (__gthread_t __threadid)
{
return __gthrw_(pthread_detach) (__threadid);
}
static inline int
__gthread_equal (__gthread_t __t1, __gthread_t __t2)
{
return __gthrw_(pthread_equal) (__t1, __t2);
}
static inline __gthread_t
__gthread_self (void)
{
return __gthrw_(pthread_self) ();
}
static inline int
__gthread_yield (void)
{
return __gthrw_(sched_yield) ();
}
static inline int
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
{
if (__gthread_active_p ())
return __gthrw_(pthread_once) (__once, __func);
else
return -1;
}
static inline int
__gthread_key_create (__gthread_key_t *__key, void (*__dtor) (void *))
{
return __gthrw_(pthread_key_create) (__key, __dtor);
}
static inline int
__gthread_key_delete (__gthread_key_t __key)
{
return __gthrw_(pthread_key_delete) (__key);
}
static inline void *
__gthread_getspecific (__gthread_key_t __key)
{
return __gthrw_(pthread_getspecific) (__key);
}
static inline int
__gthread_setspecific (__gthread_key_t __key, const void *__ptr)
{
return __gthrw_(pthread_setspecific) (__key, __ptr);
}
static inline void
__gthread_mutex_init_function (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
__gthrw_(pthread_mutex_init) (__mutex, NULL);
}
static inline int
__gthread_mutex_destroy (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_destroy) (__mutex);
else
return 0;
}
static inline int
__gthread_mutex_lock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_lock) (__mutex);
else
return 0;
}
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_trylock) (__mutex);
else
return 0;
}
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
static inline int
__gthread_mutex_timedlock (__gthread_mutex_t *__mutex,
const __gthread_time_t *__abs_timeout)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_timedlock) (__mutex, __abs_timeout);
else
return 0;
}
#endif
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *__mutex)
{
if (__gthread_active_p ())
return __gthrw_(pthread_mutex_unlock) (__mutex);
else
return 0;
}
#if !defined( PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) \
|| defined(_GTHREAD_USE_RECURSIVE_MUTEX_INIT_FUNC)
static inline int
__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
{
if (__gthread_active_p ())
{
pthread_mutexattr_t __attr;
int __r;
__r = __gthrw_(pthread_mutexattr_init) (&__attr);
if (!__r)
__r = __gthrw_(pthread_mutexattr_settype) (&__attr,
PTHREAD_MUTEX_RECURSIVE);
if (!__r)
__r = __gthrw_(pthread_mutex_init) (__mutex, &__attr);
if (!__r)
__r = __gthrw_(pthread_mutexattr_destroy) (&__attr);
return __r;
}
return 0;
}
#endif
static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_lock (__mutex);
}
static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_trylock (__mutex);
}
#if _GTHREAD_USE_MUTEX_TIMEDLOCK
static inline int
__gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *__mutex,
const __gthread_time_t *__abs_timeout)
{
return __gthread_mutex_timedlock (__mutex, __abs_timeout);
}
#endif
static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_unlock (__mutex);
}
static inline int
__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_destroy (__mutex);
}
#ifdef _GTHREAD_USE_COND_INIT_FUNC
static inline void
__gthread_cond_init_function (__gthread_cond_t *__cond)
{
if (__gthread_active_p ())
__gthrw_(pthread_cond_init) (__cond, NULL);
}
#endif
static inline int
__gthread_cond_broadcast (__gthread_cond_t *__cond)
{
return __gthrw_(pthread_cond_broadcast) (__cond);
}
static inline int
__gthread_cond_signal (__gthread_cond_t *__cond)
{
return __gthrw_(pthread_cond_signal) (__cond);
}
static inline int
__gthread_cond_wait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex)
{
return __gthrw_(pthread_cond_wait) (__cond, __mutex);
}
static inline int
__gthread_cond_timedwait (__gthread_cond_t *__cond, __gthread_mutex_t *__mutex,
const __gthread_time_t *__abs_timeout)
{
return __gthrw_(pthread_cond_timedwait) (__cond, __mutex, __abs_timeout);
}
static inline int
__gthread_cond_wait_recursive (__gthread_cond_t *__cond,
__gthread_recursive_mutex_t *__mutex)
{
return __gthread_cond_wait (__cond, __mutex);
}
static inline int
__gthread_cond_destroy (__gthread_cond_t* __cond)
{
return __gthrw_(pthread_cond_destroy) (__cond);
}
#endif /* _LIBOBJC */
#endif /* ! _GLIBCXX_GCC_GTHR_POSIX_H */

View File

@ -0,0 +1,298 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GLIBCXX_GCC_GTHR_SINGLE_H
#define _GLIBCXX_GCC_GTHR_SINGLE_H
/* Just provide compatibility for mutex handling. */
typedef int __gthread_key_t;
typedef int __gthread_once_t;
typedef int __gthread_mutex_t;
typedef int __gthread_recursive_mutex_t;
#define __GTHREAD_ONCE_INIT 0
#define __GTHREAD_MUTEX_INIT 0
#define __GTHREAD_MUTEX_INIT_FUNCTION(mx) do {} while (0)
#define __GTHREAD_RECURSIVE_MUTEX_INIT 0
#define _GLIBCXX_UNUSED __attribute__((__unused__))
#ifdef _LIBOBJC
/* Thread local storage for a single thread */
static void *thread_local_storage = NULL;
/* Backend initialization functions */
/* Initialize the threads subsystem. */
static inline int
__gthread_objc_init_thread_system (void)
{
/* No thread support available */
return -1;
}
/* Close the threads subsystem. */
static inline int
__gthread_objc_close_thread_system (void)
{
/* No thread support available */
return -1;
}
/* Backend thread functions */
/* Create a new thread of execution. */
static inline objc_thread_t
__gthread_objc_thread_detach (void (* func)(void *), void * arg _GLIBCXX_UNUSED)
{
/* No thread support available */
return NULL;
}
/* Set the current thread's priority. */
static inline int
__gthread_objc_thread_set_priority (int priority _GLIBCXX_UNUSED)
{
/* No thread support available */
return -1;
}
/* Return the current thread's priority. */
static inline int
__gthread_objc_thread_get_priority (void)
{
return OBJC_THREAD_INTERACTIVE_PRIORITY;
}
/* Yield our process time to another thread. */
static inline void
__gthread_objc_thread_yield (void)
{
return;
}
/* Terminate the current thread. */
static inline int
__gthread_objc_thread_exit (void)
{
/* No thread support available */
/* Should we really exit the program */
/* exit (&__objc_thread_exit_status); */
return -1;
}
/* Returns an integer value which uniquely describes a thread. */
static inline objc_thread_t
__gthread_objc_thread_id (void)
{
/* No thread support, use 1. */
return (objc_thread_t) 1;
}
/* Sets the thread's local storage pointer. */
static inline int
__gthread_objc_thread_set_data (void *value)
{
thread_local_storage = value;
return 0;
}
/* Returns the thread's local storage pointer. */
static inline void *
__gthread_objc_thread_get_data (void)
{
return thread_local_storage;
}
/* Backend mutex functions */
/* Allocate a mutex. */
static inline int
__gthread_objc_mutex_allocate (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Deallocate a mutex. */
static inline int
__gthread_objc_mutex_deallocate (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_lock (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
/* There can only be one thread, so we always get the lock */
return 0;
}
/* Try to grab a lock on a mutex. */
static inline int
__gthread_objc_mutex_trylock (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
/* There can only be one thread, so we always get the lock */
return 0;
}
/* Unlock the mutex */
static inline int
__gthread_objc_mutex_unlock (objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Backend condition mutex functions */
/* Allocate a condition. */
static inline int
__gthread_objc_condition_allocate (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
/* Deallocate a condition. */
static inline int
__gthread_objc_condition_deallocate (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
/* Wait on the condition */
static inline int
__gthread_objc_condition_wait (objc_condition_t condition _GLIBCXX_UNUSED,
objc_mutex_t mutex _GLIBCXX_UNUSED)
{
return 0;
}
/* Wake up all threads waiting on this condition. */
static inline int
__gthread_objc_condition_broadcast (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
/* Wake up one thread waiting on this condition. */
static inline int
__gthread_objc_condition_signal (objc_condition_t condition _GLIBCXX_UNUSED)
{
return 0;
}
#else /* _LIBOBJC */
static inline int
__gthread_active_p (void)
{
return 0;
}
static inline int
__gthread_once (__gthread_once_t *__once _GLIBCXX_UNUSED, void (*__func) (void) _GLIBCXX_UNUSED)
{
return 0;
}
static inline int _GLIBCXX_UNUSED
__gthread_key_create (__gthread_key_t *__key _GLIBCXX_UNUSED, void (*__func) (void *) _GLIBCXX_UNUSED)
{
return 0;
}
static int _GLIBCXX_UNUSED
__gthread_key_delete (__gthread_key_t __key _GLIBCXX_UNUSED)
{
return 0;
}
static inline void *
__gthread_getspecific (__gthread_key_t __key _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_setspecific (__gthread_key_t __key _GLIBCXX_UNUSED, const void *__v _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_destroy (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_lock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_trylock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_mutex_unlock (__gthread_mutex_t *__mutex _GLIBCXX_UNUSED)
{
return 0;
}
static inline int
__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_lock (__mutex);
}
static inline int
__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_trylock (__mutex);
}
static inline int
__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_unlock (__mutex);
}
static inline int
__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
{
return __gthread_mutex_destroy (__mutex);
}
#endif /* _LIBOBJC */
#undef _GLIBCXX_UNUSED
#endif /* ! _GLIBCXX_GCC_GTHR_SINGLE_H */

View File

@ -0,0 +1,154 @@
/* Threads compatibility routines for libgcc2. */
/* Compile this one with gcc. */
/* Copyright (C) 1997-2020 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef _GLIBCXX_GCC_GTHR_H
#define _GLIBCXX_GCC_GTHR_H
#ifndef _GLIBCXX_HIDE_EXPORTS
#pragma GCC visibility push(default)
#endif
/* If this file is compiled with threads support, it must
#define __GTHREADS 1
to indicate that threads support is present. Also it has define
function
int __gthread_active_p ()
that returns 1 if thread system is active, 0 if not.
The threads interface must define the following types:
__gthread_key_t
__gthread_once_t
__gthread_mutex_t
__gthread_recursive_mutex_t
The threads interface must define the following macros:
__GTHREAD_ONCE_INIT
to initialize __gthread_once_t
__GTHREAD_MUTEX_INIT
to initialize __gthread_mutex_t to get a fast
non-recursive mutex.
__GTHREAD_MUTEX_INIT_FUNCTION
to initialize __gthread_mutex_t to get a fast
non-recursive mutex.
Define this to a function which looks like this:
void __GTHREAD_MUTEX_INIT_FUNCTION (__gthread_mutex_t *)
Some systems can't initialize a mutex without a
function call. Don't define __GTHREAD_MUTEX_INIT in this case.
__GTHREAD_RECURSIVE_MUTEX_INIT
__GTHREAD_RECURSIVE_MUTEX_INIT_FUNCTION
as above, but for a recursive mutex.
The threads interface must define the following static functions:
int __gthread_once (__gthread_once_t *once, void (*func) ())
int __gthread_key_create (__gthread_key_t *keyp, void (*dtor) (void *))
int __gthread_key_delete (__gthread_key_t key)
void *__gthread_getspecific (__gthread_key_t key)
int __gthread_setspecific (__gthread_key_t key, const void *ptr)
int __gthread_mutex_destroy (__gthread_mutex_t *mutex);
int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *mutex);
int __gthread_mutex_lock (__gthread_mutex_t *mutex);
int __gthread_mutex_trylock (__gthread_mutex_t *mutex);
int __gthread_mutex_unlock (__gthread_mutex_t *mutex);
int __gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *mutex);
int __gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *mutex);
int __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex);
The following are supported in POSIX threads only. They are required to
fix a deadlock in static initialization inside libsupc++. The header file
gthr-posix.h defines a symbol __GTHREAD_HAS_COND to signify that these extra
features are supported.
Types:
__gthread_cond_t
Macros:
__GTHREAD_COND_INIT
__GTHREAD_COND_INIT_FUNCTION
Interface:
int __gthread_cond_broadcast (__gthread_cond_t *cond);
int __gthread_cond_wait (__gthread_cond_t *cond, __gthread_mutex_t *mutex);
int __gthread_cond_wait_recursive (__gthread_cond_t *cond,
__gthread_recursive_mutex_t *mutex);
All functions returning int should return zero on success or the error
number. If the operation is not supported, -1 is returned.
If the following are also defined, you should
#define __GTHREADS_CXX0X 1
to enable the c++0x thread library.
Types:
__gthread_t
__gthread_time_t
Interface:
int __gthread_create (__gthread_t *thread, void *(*func) (void*),
void *args);
int __gthread_join (__gthread_t thread, void **value_ptr);
int __gthread_detach (__gthread_t thread);
int __gthread_equal (__gthread_t t1, __gthread_t t2);
__gthread_t __gthread_self (void);
int __gthread_yield (void);
int __gthread_mutex_timedlock (__gthread_mutex_t *m,
const __gthread_time_t *abs_timeout);
int __gthread_recursive_mutex_timedlock (__gthread_recursive_mutex_t *m,
const __gthread_time_t *abs_time);
int __gthread_cond_signal (__gthread_cond_t *cond);
int __gthread_cond_timedwait (__gthread_cond_t *cond,
__gthread_mutex_t *mutex,
const __gthread_time_t *abs_timeout);
*/
#if __GXX_WEAK__
/* The pe-coff weak support isn't fully compatible to ELF's weak.
For static libraries it might would work, but as we need to deal
with shared versions too, we disable it for mingw-targets. */
#ifdef __MINGW32__
#undef _GLIBCXX_GTHREAD_USE_WEAK
#define _GLIBCXX_GTHREAD_USE_WEAK 0
#endif
#ifndef _GLIBCXX_GTHREAD_USE_WEAK
#define _GLIBCXX_GTHREAD_USE_WEAK 1
#endif
#endif
#include <bits/gthr-default.h>
#ifndef _GLIBCXX_HIDE_EXPORTS
#pragma GCC visibility pop
#endif
#endif /* ! _GLIBCXX_GCC_GTHR_H */

View File

@ -0,0 +1,151 @@
// std::messages implementation details, GNU version -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/messages_members.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.2.7.1.2 messages functions
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#include <libintl.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Non-virtual member functions.
template<typename _CharT>
messages<_CharT>::messages(size_t __refs)
: facet(__refs), _M_c_locale_messages(_S_get_c_locale()),
_M_name_messages(_S_get_c_name())
{ }
template<typename _CharT>
messages<_CharT>::messages(__c_locale __cloc, const char* __s,
size_t __refs)
: facet(__refs), _M_c_locale_messages(0), _M_name_messages(0)
{
if (__builtin_strcmp(__s, _S_get_c_name()) != 0)
{
const size_t __len = __builtin_strlen(__s) + 1;
char* __tmp = new char[__len];
__builtin_memcpy(__tmp, __s, __len);
_M_name_messages = __tmp;
}
else
_M_name_messages = _S_get_c_name();
// Last to avoid leaking memory if new throws.
_M_c_locale_messages = _S_clone_c_locale(__cloc);
}
template<typename _CharT>
typename messages<_CharT>::catalog
messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc,
const char* __dir) const
{
bindtextdomain(__s.c_str(), __dir);
return this->do_open(__s, __loc);
}
// Virtual member functions.
template<typename _CharT>
messages<_CharT>::~messages()
{
if (_M_name_messages != _S_get_c_name())
delete [] _M_name_messages;
_S_destroy_c_locale(_M_c_locale_messages);
}
template<typename _CharT>
typename messages<_CharT>::catalog
messages<_CharT>::do_open(const basic_string<char>& __s,
const locale&) const
{
// No error checking is done, assume the catalog exists and can
// be used.
textdomain(__s.c_str());
return 0;
}
template<typename _CharT>
void
messages<_CharT>::do_close(catalog) const
{ }
// messages_byname
template<typename _CharT>
messages_byname<_CharT>::messages_byname(const char* __s, size_t __refs)
: messages<_CharT>(__refs)
{
if (this->_M_name_messages != locale::facet::_S_get_c_name())
{
delete [] this->_M_name_messages;
if (__builtin_strcmp(__s, locale::facet::_S_get_c_name()) != 0)
{
const size_t __len = __builtin_strlen(__s) + 1;
char* __tmp = new char[__len];
__builtin_memcpy(__tmp, __s, __len);
this->_M_name_messages = __tmp;
}
else
this->_M_name_messages = locale::facet::_S_get_c_name();
}
if (__builtin_strcmp(__s, "C") != 0
&& __builtin_strcmp(__s, "POSIX") != 0)
{
this->_S_destroy_c_locale(this->_M_c_locale_messages);
this->_S_create_c_locale(this->_M_c_locale_messages, __s);
}
}
//Specializations.
template<>
typename messages<char>::catalog
messages<char>::do_open(const basic_string<char>&,
const locale&) const;
template<>
void
messages<char>::do_close(catalog) const;
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
typename messages<wchar_t>::catalog
messages<wchar_t>::do_open(const basic_string<char>&,
const locale&) const;
template<>
void
messages<wchar_t>::do_close(catalog) const;
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

View File

@ -0,0 +1,47 @@
// Optimizations for random number functions, aarch64 version -*- C++ -*-
// Copyright (C) 2017-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/opt_random.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{random}
*/
#ifndef _BITS_OPT_RANDOM_H
#define _BITS_OPT_RANDOM_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY (default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // _BITS_OPT_RANDOM_H

View File

@ -0,0 +1,64 @@
// Specific definitions for GNU/Linux -*- C++ -*-
// Copyright (C) 2000-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/os_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _GLIBCXX_OS_DEFINES
#define _GLIBCXX_OS_DEFINES 1
// System-specific #define, typedefs, corrections, etc, go here. This
// file will come before all others.
// This keeps isanum, et al from being propagated as macros.
#define __NO_CTYPE 1
#include <features.h>
// Provide a declaration for the possibly deprecated gets function, as
// glibc 2.15 and later does not declare gets for ISO C11 when
// __GNU_SOURCE is defined.
#if __GLIBC_PREREQ(2,15) && defined(_GNU_SOURCE)
# undef _GLIBCXX_HAVE_GETS
#endif
// Glibc 2.23 removed the obsolete isinf and isnan declarations. Check the
// version dynamically in case it has changed since libstdc++ was configured.
#define _GLIBCXX_NO_OBSOLETE_ISINF_ISNAN_DYNAMIC __GLIBC_PREREQ(2,23)
#if __GLIBC_PREREQ(2, 27)
// Since glibc 2.27 pthread_self() is usable without linking to libpthread.
# define _GLIBCXX_NATIVE_THREAD_ID pthread_self()
#else
// Before then it was in libc.so.6 but not libc.a, and always returns 0,
// which breaks the invariant this_thread::get_id() != thread::id{}.
// So only use it if we know the libpthread version is available.
// Otherwise use (__gthread_t)1 as the ID of the main (and only) thread.
# define _GLIBCXX_NATIVE_THREAD_ID \
(__gthread_active_p() ? __gthread_self() : (__gthread_t)1)
#endif
#endif

View File

@ -0,0 +1,149 @@
// C++ includes used for precompiling -*- C++ -*-
// Copyright (C) 2003-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file stdc++.h
* This is an implementation file for a precompiled header.
*/
// 17.4.1.2 Headers
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cwchar>
#include <cwctype>
#if __cplusplus >= 201103L
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdalign>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cuchar>
#endif
// C++
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <codecvt>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif
#if __cplusplus >= 201402L
#include <shared_mutex>
#endif
#if __cplusplus >= 201703L
#include <any>
#include <charconv>
// #include <execution>
#include <filesystem>
#include <optional>
#include <memory_resource>
#include <string_view>
#include <variant>
#endif
#if __cplusplus > 201703L
#include <bit>
#include <compare>
#include <concepts>
#if __cpp_impl_coroutine
# include <coroutine>
#endif
#include <numbers>
#include <ranges>
#include <span>
#include <stop_token>
// #include <syncstream>
#include <version>
#endif

View File

@ -0,0 +1,53 @@
// C++ includes used for precompiling TR1 -*- C++ -*-
// Copyright (C) 2006-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file stdtr1c++.h
* This is an implementation file for a precompiled header.
*/
#include <bits/stdc++.h>
#include <tr1/array>
#include <tr1/cctype>
#include <tr1/cfenv>
#include <tr1/cfloat>
#include <tr1/cinttypes>
#include <tr1/climits>
#include <tr1/cmath>
#include <tr1/complex>
#include <tr1/cstdarg>
#include <tr1/cstdbool>
#include <tr1/cstdint>
#include <tr1/cstdio>
#include <tr1/cstdlib>
#include <tr1/ctgmath>
#include <tr1/ctime>
#include <tr1/cwchar>
#include <tr1/cwctype>
#include <tr1/functional>
#include <tr1/random>
#include <tr1/tuple>
#include <tr1/unordered_map>
#include <tr1/unordered_set>
#include <tr1/utility>

View File

@ -0,0 +1,89 @@
// std::time_get, std::time_put implementation, GNU version -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/time_members.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.2.5.1.2 - time_get functions
// ISO C++ 14882: 22.2.5.3.2 - time_put functions
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT>
__timepunct<_CharT>::__timepunct(size_t __refs)
: facet(__refs), _M_data(0), _M_c_locale_timepunct(0),
_M_name_timepunct(_S_get_c_name())
{ _M_initialize_timepunct(); }
template<typename _CharT>
__timepunct<_CharT>::__timepunct(__cache_type* __cache, size_t __refs)
: facet(__refs), _M_data(__cache), _M_c_locale_timepunct(0),
_M_name_timepunct(_S_get_c_name())
{ _M_initialize_timepunct(); }
template<typename _CharT>
__timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
size_t __refs)
: facet(__refs), _M_data(0), _M_c_locale_timepunct(0),
_M_name_timepunct(0)
{
if (__builtin_strcmp(__s, _S_get_c_name()) != 0)
{
const size_t __len = __builtin_strlen(__s) + 1;
char* __tmp = new char[__len];
__builtin_memcpy(__tmp, __s, __len);
_M_name_timepunct = __tmp;
}
else
_M_name_timepunct = _S_get_c_name();
__try
{ _M_initialize_timepunct(__cloc); }
__catch(...)
{
if (_M_name_timepunct != _S_get_c_name())
delete [] _M_name_timepunct;
__throw_exception_again;
}
}
template<typename _CharT>
__timepunct<_CharT>::~__timepunct()
{
if (_M_name_timepunct != _S_get_c_name())
delete [] _M_name_timepunct;
delete _M_data;
_S_destroy_c_locale(_M_c_locale_timepunct);
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

View File

@ -0,0 +1,182 @@
// Optimizations for random number extensions, aarch64 version -*- C++ -*-
// Copyright (C) 2017-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file ext/random.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ext/random}
*/
#ifndef _EXT_OPT_RANDOM_H
#define _EXT_OPT_RANDOM_H 1
#pragma GCC system_header
#ifdef __ARM_NEON
#ifdef __ARM_BIG_ENDIAN
# define __VEXT(_A,_B,_C) __builtin_shuffle (_A, _B, (__Uint8x16_t) \
{16-_C, 17-_C, 18-_C, 19-_C, 20-_C, 21-_C, 22-_C, 23-_C, \
24-_C, 25-_C, 26-_C, 27-_C, 28-_C, 29-_C, 30-_C, 31-_C})
#else
# define __VEXT(_A,_B,_C) __builtin_shuffle (_B, _A, (__Uint8x16_t) \
{_C, _C+1, _C+2, _C+3, _C+4, _C+5, _C+6, _C+7, \
_C+8, _C+9, _C+10, _C+11, _C+12, _C+13, _C+14, _C+15})
#endif
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
namespace __gnu_cxx _GLIBCXX_VISIBILITY (default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace {
// Logical Shift right 128-bits by c * 8 bits
__extension__ extern __inline __Uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__aarch64_lsr_128 (__Uint8x16_t __a, __const int __c)
{
const __Uint8x16_t __zero = {0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
return (__Uint32x4_t) __VEXT (__zero, __a, __c);
}
// Logical Shift left 128-bits by c * 8 bits
__extension__ extern __inline __Uint32x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__aarch64_lsl_128 (__Uint8x16_t __a, __const int __c)
{
const __Uint8x16_t __zero = {0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0};
return (__Uint32x4_t) __VEXT (__a, __zero, 16 - __c);
}
template<size_t __sl1, size_t __sl2, size_t __sr1, size_t __sr2>
inline __Uint32x4_t __aarch64_recursion (__Uint32x4_t __a,
__Uint32x4_t __b,
__Uint32x4_t __c,
__Uint32x4_t __d,
__Uint32x4_t __e)
{
__Uint32x4_t __y = (__b >> __sr1);
__Uint32x4_t __z = __aarch64_lsr_128 ((__Uint8x16_t) __c, __sr2);
__Uint32x4_t __v = __d << __sl1;
__z = __z ^ __a;
__z = __z ^ __v;
__Uint32x4_t __x = __aarch64_lsl_128 ((__Uint8x16_t) __a, __sl2);
__y = __y & __e;
__z = __z ^ __x;
return __z ^ __y;
}
}
#define _GLIBCXX_OPT_HAVE_RANDOM_SFMT_GEN_READ 1
template<typename _UIntType, size_t __m,
size_t __pos1, size_t __sl1, size_t __sl2,
size_t __sr1, size_t __sr2,
uint32_t __msk1, uint32_t __msk2,
uint32_t __msk3, uint32_t __msk4,
uint32_t __parity1, uint32_t __parity2,
uint32_t __parity3, uint32_t __parity4>
void simd_fast_mersenne_twister_engine<_UIntType, __m,
__pos1, __sl1, __sl2, __sr1, __sr2,
__msk1, __msk2, __msk3, __msk4,
__parity1, __parity2, __parity3,
__parity4>::
_M_gen_rand (void)
{
__Uint32x4_t __r1 = _M_state[_M_nstate - 2];
__Uint32x4_t __r2 = _M_state[_M_nstate - 1];
__Uint32x4_t __aData = {__msk1, __msk2, __msk3, __msk4};
size_t __i;
for (__i = 0; __i < _M_nstate - __pos1; ++__i)
{
__Uint32x4_t __r = __aarch64_recursion<__sl1, __sl2, __sr1, __sr2>
(_M_state[__i], _M_state[__i + __pos1], __r1, __r2, __aData);
_M_state[__i] = __r;
__r1 = __r2;
__r2 = __r;
}
for (; __i < _M_nstate; ++__i)
{
__Uint32x4_t __r = __aarch64_recursion<__sl1, __sl2, __sr1, __sr2>
(_M_state[__i], _M_state[__i + __pos1 - _M_nstate], __r1, __r2,
__aData);
_M_state[__i] = __r;
__r1 = __r2;
__r2 = __r;
}
_M_pos = 0;
}
#define _GLIBCXX_OPT_HAVE_RANDOM_SFMT_OPERATOREQUAL 1
template<typename _UIntType, size_t __m,
size_t __pos1, size_t __sl1, size_t __sl2,
size_t __sr1, size_t __sr2,
uint32_t __msk1, uint32_t __msk2,
uint32_t __msk3, uint32_t __msk4,
uint32_t __parity1, uint32_t __parity2,
uint32_t __parity3, uint32_t __parity4>
bool
operator==(const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
__m, __pos1, __sl1, __sl2, __sr1, __sr2,
__msk1, __msk2, __msk3, __msk4,
__parity1, __parity2, __parity3, __parity4>& __lhs,
const __gnu_cxx::simd_fast_mersenne_twister_engine<_UIntType,
__m, __pos1, __sl1, __sl2, __sr1, __sr2,
__msk1, __msk2, __msk3, __msk4,
__parity1, __parity2, __parity3, __parity4>& __rhs)
{
if (__lhs._M_pos != __rhs._M_pos)
return false;
__Uint32x4_t __res = __lhs._M_state[0] ^ __rhs._M_state[0];
for (size_t __i = 1; __i < __lhs._M_nstate; ++__i)
__res |= __lhs._M_state[__i] ^ __rhs._M_state[__i];
return (__int128) __res == 0;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#endif // __ARM_NEON
#endif // _EXT_OPT_RANDOM_H

View File

@ -0,0 +1,86 @@
// <algorithm> -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996,1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file include/algorithm
* This is a Standard C++ Library header.
*/
#ifndef _GLIBCXX_ALGORITHM
#define _GLIBCXX_ALGORITHM 1
#pragma GCC system_header
#include <utility> // UK-300.
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
#if __cplusplus > 201703L
# include <bits/ranges_algo.h>
#endif
#if __cplusplus > 201402L
// Parallel STL algorithms
# if _PSTL_EXECUTION_POLICIES_DEFINED
// If <execution> has already been included, pull in implementations
# include <pstl/glue_algorithm_impl.h>
# else
// Otherwise just pull in forward declarations
# include <pstl/glue_algorithm_defs.h>
# define _PSTL_ALGORITHM_FORWARD_DECLARED 1
# endif
// Feature test macro for parallel algorithms
# define __cpp_lib_parallel_algorithm 201603L
#endif // C++17
#ifdef _GLIBCXX_PARALLEL
# include <parallel/algorithm>
#endif
#endif /* _GLIBCXX_ALGORITHM */

View File

@ -0,0 +1,636 @@
// <any> -*- C++ -*-
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/any
* This is a Standard C++ Library header.
*/
#ifndef _GLIBCXX_ANY
#define _GLIBCXX_ANY 1
#pragma GCC system_header
#if __cplusplus >= 201703L
#include <typeinfo>
#include <new>
#include <utility>
#include <type_traits>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup utilities
* @{
*/
/**
* @brief Exception class thrown by a failed @c any_cast
* @ingroup exceptions
*/
class bad_any_cast : public bad_cast
{
public:
virtual const char* what() const noexcept { return "bad any_cast"; }
};
[[gnu::noreturn]] inline void __throw_bad_any_cast()
{
#if __cpp_exceptions
throw bad_any_cast{};
#else
__builtin_abort();
#endif
}
#define __cpp_lib_any 201606L
/**
* @brief A type-safe container of any type.
*
* An @c any object's state is either empty or it stores a contained object
* of CopyConstructible type.
*/
class any
{
// Holds either pointer to a heap object or the contained object itself.
union _Storage
{
constexpr _Storage() : _M_ptr{nullptr} {}
// Prevent trivial copies of this type, buffer might hold a non-POD.
_Storage(const _Storage&) = delete;
_Storage& operator=(const _Storage&) = delete;
void* _M_ptr;
aligned_storage<sizeof(_M_ptr), alignof(void*)>::type _M_buffer;
};
template<typename _Tp, typename _Safe = is_nothrow_move_constructible<_Tp>,
bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))
&& (alignof(_Tp) <= alignof(_Storage))>
using _Internal = std::integral_constant<bool, _Safe::value && _Fits>;
template<typename _Tp>
struct _Manager_internal; // uses small-object optimization
template<typename _Tp>
struct _Manager_external; // creates contained object on the heap
template<typename _Tp>
using _Manager = conditional_t<_Internal<_Tp>::value,
_Manager_internal<_Tp>,
_Manager_external<_Tp>>;
template<typename _Tp, typename _VTp = decay_t<_Tp>>
using _Decay_if_not_any = enable_if_t<!is_same_v<_VTp, any>, _VTp>;
/// Emplace with an object created from @p __args as the contained object.
template <typename _Tp, typename... _Args,
typename _Mgr = _Manager<_Tp>>
void __do_emplace(_Args&&... __args)
{
reset();
_Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
_M_manager = &_Mgr::_S_manage;
}
/// Emplace with an object created from @p __il and @p __args as
/// the contained object.
template <typename _Tp, typename _Up, typename... _Args,
typename _Mgr = _Manager<_Tp>>
void __do_emplace(initializer_list<_Up> __il, _Args&&... __args)
{
reset();
_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
_M_manager = &_Mgr::_S_manage;
}
template <typename _Res, typename _Tp, typename... _Args>
using __any_constructible
= enable_if<__and_<is_copy_constructible<_Tp>,
is_constructible<_Tp, _Args...>>::value,
_Res>;
template <typename _Tp, typename... _Args>
using __any_constructible_t
= typename __any_constructible<bool, _Tp, _Args...>::type;
template<typename _VTp, typename... _Args>
using __emplace_t
= typename __any_constructible<_VTp&, _VTp, _Args...>::type;
public:
// construct/destruct
/// Default constructor, creates an empty object.
constexpr any() noexcept : _M_manager(nullptr) { }
/// Copy constructor, copies the state of @p __other
any(const any& __other)
{
if (!__other.has_value())
_M_manager = nullptr;
else
{
_Arg __arg;
__arg._M_any = this;
__other._M_manager(_Op_clone, &__other, &__arg);
}
}
/**
* @brief Move constructor, transfer the state from @p __other
*
* @post @c !__other.has_value() (this postcondition is a GNU extension)
*/
any(any&& __other) noexcept
{
if (!__other.has_value())
_M_manager = nullptr;
else
{
_Arg __arg;
__arg._M_any = this;
__other._M_manager(_Op_xfer, &__other, &__arg);
}
}
/// Construct with a copy of @p __value as the contained object.
template <typename _Tp, typename _VTp = _Decay_if_not_any<_Tp>,
typename _Mgr = _Manager<_VTp>,
enable_if_t<is_copy_constructible<_VTp>::value
&& !__is_in_place_type<_VTp>::value, bool> = true>
any(_Tp&& __value)
: _M_manager(&_Mgr::_S_manage)
{
_Mgr::_S_create(_M_storage, std::forward<_Tp>(__value));
}
/// Construct with an object created from @p __args as the contained object.
template <typename _Tp, typename... _Args, typename _VTp = decay_t<_Tp>,
typename _Mgr = _Manager<_VTp>,
__any_constructible_t<_VTp, _Args&&...> = false>
explicit
any(in_place_type_t<_Tp>, _Args&&... __args)
: _M_manager(&_Mgr::_S_manage)
{
_Mgr::_S_create(_M_storage, std::forward<_Args>(__args)...);
}
/// Construct with an object created from @p __il and @p __args as
/// the contained object.
template <typename _Tp, typename _Up, typename... _Args,
typename _VTp = decay_t<_Tp>, typename _Mgr = _Manager<_VTp>,
__any_constructible_t<_VTp, initializer_list<_Up>&,
_Args&&...> = false>
explicit
any(in_place_type_t<_Tp>, initializer_list<_Up> __il, _Args&&... __args)
: _M_manager(&_Mgr::_S_manage)
{
_Mgr::_S_create(_M_storage, __il, std::forward<_Args>(__args)...);
}
/// Destructor, calls @c reset()
~any() { reset(); }
// assignments
/// Copy the state of another object.
any&
operator=(const any& __rhs)
{
*this = any(__rhs);
return *this;
}
/**
* @brief Move assignment operator
*
* @post @c !__rhs.has_value() (not guaranteed for other implementations)
*/
any&
operator=(any&& __rhs) noexcept
{
if (!__rhs.has_value())
reset();
else if (this != &__rhs)
{
reset();
_Arg __arg;
__arg._M_any = this;
__rhs._M_manager(_Op_xfer, &__rhs, &__arg);
}
return *this;
}
/// Store a copy of @p __rhs as the contained object.
template<typename _Tp>
enable_if_t<is_copy_constructible<_Decay_if_not_any<_Tp>>::value, any&>
operator=(_Tp&& __rhs)
{
*this = any(std::forward<_Tp>(__rhs));
return *this;
}
/// Emplace with an object created from @p __args as the contained object.
template <typename _Tp, typename... _Args>
__emplace_t<decay_t<_Tp>, _Args...>
emplace(_Args&&... __args)
{
using _VTp = decay_t<_Tp>;
__do_emplace<_VTp>(std::forward<_Args>(__args)...);
any::_Arg __arg;
this->_M_manager(any::_Op_access, this, &__arg);
return *static_cast<_VTp*>(__arg._M_obj);
}
/// Emplace with an object created from @p __il and @p __args as
/// the contained object.
template <typename _Tp, typename _Up, typename... _Args>
__emplace_t<decay_t<_Tp>, initializer_list<_Up>&, _Args&&...>
emplace(initializer_list<_Up> __il, _Args&&... __args)
{
using _VTp = decay_t<_Tp>;
__do_emplace<_VTp, _Up>(__il, std::forward<_Args>(__args)...);
any::_Arg __arg;
this->_M_manager(any::_Op_access, this, &__arg);
return *static_cast<_VTp*>(__arg._M_obj);
}
// modifiers
/// If not empty, destroy the contained object.
void reset() noexcept
{
if (has_value())
{
_M_manager(_Op_destroy, this, nullptr);
_M_manager = nullptr;
}
}
/// Exchange state with another object.
void swap(any& __rhs) noexcept
{
if (!has_value() && !__rhs.has_value())
return;
if (has_value() && __rhs.has_value())
{
if (this == &__rhs)
return;
any __tmp;
_Arg __arg;
__arg._M_any = &__tmp;
__rhs._M_manager(_Op_xfer, &__rhs, &__arg);
__arg._M_any = &__rhs;
_M_manager(_Op_xfer, this, &__arg);
__arg._M_any = this;
__tmp._M_manager(_Op_xfer, &__tmp, &__arg);
}
else
{
any* __empty = !has_value() ? this : &__rhs;
any* __full = !has_value() ? &__rhs : this;
_Arg __arg;
__arg._M_any = __empty;
__full->_M_manager(_Op_xfer, __full, &__arg);
}
}
// observers
/// Reports whether there is a contained object or not.
bool has_value() const noexcept { return _M_manager != nullptr; }
#if __cpp_rtti
/// The @c typeid of the contained object, or @c typeid(void) if empty.
const type_info& type() const noexcept
{
if (!has_value())
return typeid(void);
_Arg __arg;
_M_manager(_Op_get_type_info, this, &__arg);
return *__arg._M_typeinfo;
}
#endif
template<typename _Tp>
static constexpr bool __is_valid_cast()
{ return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
private:
enum _Op {
_Op_access, _Op_get_type_info, _Op_clone, _Op_destroy, _Op_xfer
};
union _Arg
{
void* _M_obj;
const std::type_info* _M_typeinfo;
any* _M_any;
};
void (*_M_manager)(_Op, const any*, _Arg*);
_Storage _M_storage;
template<typename _Tp>
friend void* __any_caster(const any* __any);
// Manage in-place contained object.
template<typename _Tp>
struct _Manager_internal
{
static void
_S_manage(_Op __which, const any* __anyp, _Arg* __arg);
template<typename _Up>
static void
_S_create(_Storage& __storage, _Up&& __value)
{
void* __addr = &__storage._M_buffer;
::new (__addr) _Tp(std::forward<_Up>(__value));
}
template<typename... _Args>
static void
_S_create(_Storage& __storage, _Args&&... __args)
{
void* __addr = &__storage._M_buffer;
::new (__addr) _Tp(std::forward<_Args>(__args)...);
}
};
// Manage external contained object.
template<typename _Tp>
struct _Manager_external
{
static void
_S_manage(_Op __which, const any* __anyp, _Arg* __arg);
template<typename _Up>
static void
_S_create(_Storage& __storage, _Up&& __value)
{
__storage._M_ptr = new _Tp(std::forward<_Up>(__value));
}
template<typename... _Args>
static void
_S_create(_Storage& __storage, _Args&&... __args)
{
__storage._M_ptr = new _Tp(std::forward<_Args>(__args)...);
}
};
};
/// Exchange the states of two @c any objects.
inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); }
/// Create an any holding a @c _Tp constructed from @c __args.
template <typename _Tp, typename... _Args>
any make_any(_Args&&... __args)
{
return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
}
/// Create an any holding a @c _Tp constructed from @c __il and @c __args.
template <typename _Tp, typename _Up, typename... _Args>
any make_any(initializer_list<_Up> __il, _Args&&... __args)
{
return any(in_place_type<_Tp>, __il, std::forward<_Args>(__args)...);
}
/**
* @brief Access the contained object.
*
* @tparam _ValueType A const-reference or CopyConstructible type.
* @param __any The object to access.
* @return The contained object.
* @throw bad_any_cast If <code>
* __any.type() != typeid(remove_reference_t<_ValueType>)
* </code>
*/
template<typename _ValueType>
inline _ValueType any_cast(const any& __any)
{
using _Up = __remove_cvref_t<_ValueType>;
static_assert(any::__is_valid_cast<_ValueType>(),
"Template argument must be a reference or CopyConstructible type");
static_assert(is_constructible_v<_ValueType, const _Up&>,
"Template argument must be constructible from a const value.");
auto __p = any_cast<_Up>(&__any);
if (__p)
return static_cast<_ValueType>(*__p);
__throw_bad_any_cast();
}
/**
* @brief Access the contained object.
*
* @tparam _ValueType A reference or CopyConstructible type.
* @param __any The object to access.
* @return The contained object.
* @throw bad_any_cast If <code>
* __any.type() != typeid(remove_reference_t<_ValueType>)
* </code>
*
* @{
*/
template<typename _ValueType>
inline _ValueType any_cast(any& __any)
{
using _Up = __remove_cvref_t<_ValueType>;
static_assert(any::__is_valid_cast<_ValueType>(),
"Template argument must be a reference or CopyConstructible type");
static_assert(is_constructible_v<_ValueType, _Up&>,
"Template argument must be constructible from an lvalue.");
auto __p = any_cast<_Up>(&__any);
if (__p)
return static_cast<_ValueType>(*__p);
__throw_bad_any_cast();
}
template<typename _ValueType>
inline _ValueType any_cast(any&& __any)
{
using _Up = __remove_cvref_t<_ValueType>;
static_assert(any::__is_valid_cast<_ValueType>(),
"Template argument must be a reference or CopyConstructible type");
static_assert(is_constructible_v<_ValueType, _Up>,
"Template argument must be constructible from an rvalue.");
auto __p = any_cast<_Up>(&__any);
if (__p)
return static_cast<_ValueType>(std::move(*__p));
__throw_bad_any_cast();
}
/// @}
/// @cond undocumented
template<typename _Tp>
void* __any_caster(const any* __any)
{
// any_cast<T> returns non-null if __any->type() == typeid(T) and
// typeid(T) ignores cv-qualifiers so remove them:
using _Up = remove_cv_t<_Tp>;
// The contained value has a decayed type, so if decay_t<U> is not U,
// then it's not possible to have a contained value of type U:
if constexpr (!is_same_v<decay_t<_Up>, _Up>)
return nullptr;
// Only copy constructible types can be used for contained values:
else if constexpr (!is_copy_constructible_v<_Up>)
return nullptr;
// First try comparing function addresses, which works without RTTI
else if (__any->_M_manager == &any::_Manager<_Up>::_S_manage
#if __cpp_rtti
|| __any->type() == typeid(_Tp)
#endif
)
{
any::_Arg __arg;
__any->_M_manager(any::_Op_access, __any, &__arg);
return __arg._M_obj;
}
return nullptr;
}
/// @endcond
/**
* @brief Access the contained object.
*
* @tparam _ValueType The type of the contained object.
* @param __any A pointer to the object to access.
* @return The address of the contained object if <code>
* __any != nullptr && __any.type() == typeid(_ValueType)
* </code>, otherwise a null pointer.
*
* @{
*/
template<typename _ValueType>
inline const _ValueType* any_cast(const any* __any) noexcept
{
if constexpr (is_object_v<_ValueType>)
if (__any)
return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
return nullptr;
}
template<typename _ValueType>
inline _ValueType* any_cast(any* __any) noexcept
{
if constexpr (is_object_v<_ValueType>)
if (__any)
return static_cast<_ValueType*>(__any_caster<_ValueType>(__any));
return nullptr;
}
/// @}
template<typename _Tp>
void
any::_Manager_internal<_Tp>::
_S_manage(_Op __which, const any* __any, _Arg* __arg)
{
// The contained object is in _M_storage._M_buffer
auto __ptr = reinterpret_cast<const _Tp*>(&__any->_M_storage._M_buffer);
switch (__which)
{
case _Op_access:
__arg->_M_obj = const_cast<_Tp*>(__ptr);
break;
case _Op_get_type_info:
#if __cpp_rtti
__arg->_M_typeinfo = &typeid(_Tp);
#endif
break;
case _Op_clone:
::new(&__arg->_M_any->_M_storage._M_buffer) _Tp(*__ptr);
__arg->_M_any->_M_manager = __any->_M_manager;
break;
case _Op_destroy:
__ptr->~_Tp();
break;
case _Op_xfer:
::new(&__arg->_M_any->_M_storage._M_buffer) _Tp
(std::move(*const_cast<_Tp*>(__ptr)));
__ptr->~_Tp();
__arg->_M_any->_M_manager = __any->_M_manager;
const_cast<any*>(__any)->_M_manager = nullptr;
break;
}
}
template<typename _Tp>
void
any::_Manager_external<_Tp>::
_S_manage(_Op __which, const any* __any, _Arg* __arg)
{
// The contained object is *_M_storage._M_ptr
auto __ptr = static_cast<const _Tp*>(__any->_M_storage._M_ptr);
switch (__which)
{
case _Op_access:
__arg->_M_obj = const_cast<_Tp*>(__ptr);
break;
case _Op_get_type_info:
#if __cpp_rtti
__arg->_M_typeinfo = &typeid(_Tp);
#endif
break;
case _Op_clone:
__arg->_M_any->_M_storage._M_ptr = new _Tp(*__ptr);
__arg->_M_any->_M_manager = __any->_M_manager;
break;
case _Op_destroy:
delete __ptr;
break;
case _Op_xfer:
__arg->_M_any->_M_storage._M_ptr = __any->_M_storage._M_ptr;
__arg->_M_any->_M_manager = __any->_M_manager;
const_cast<any*>(__any)->_M_manager = nullptr;
break;
}
}
/// @}
namespace __detail::__variant
{
template<typename> struct _Never_valueless_alt; // see <variant>
// Provide the strong exception-safety guarantee when emplacing an
// any into a variant.
template<>
struct _Never_valueless_alt<std::any>
: std::true_type
{ };
} // namespace __detail::__variant
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++17
#endif // _GLIBCXX_ANY

View File

@ -0,0 +1,451 @@
// <array> -*- C++ -*-
// Copyright (C) 2007-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/array
* This is a Standard C++ Library header.
*/
#ifndef _GLIBCXX_ARRAY
#define _GLIBCXX_ARRAY 1
#pragma GCC system_header
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
#include <utility>
#include <bits/functexcept.h>
#include <bits/stl_algobase.h>
#include <bits/range_access.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Tp, std::size_t _Nm>
struct __array_traits
{
typedef _Tp _Type[_Nm];
typedef __is_swappable<_Tp> _Is_swappable;
typedef __is_nothrow_swappable<_Tp> _Is_nothrow_swappable;
static constexpr _Tp&
_S_ref(const _Type& __t, std::size_t __n) noexcept
{ return const_cast<_Tp&>(__t[__n]); }
static constexpr _Tp*
_S_ptr(const _Type& __t) noexcept
{ return const_cast<_Tp*>(__t); }
};
template<typename _Tp>
struct __array_traits<_Tp, 0>
{
struct _Type { };
typedef true_type _Is_swappable;
typedef true_type _Is_nothrow_swappable;
static constexpr _Tp&
_S_ref(const _Type&, std::size_t) noexcept
{ return *static_cast<_Tp*>(nullptr); }
static constexpr _Tp*
_S_ptr(const _Type&) noexcept
{ return nullptr; }
};
/**
* @brief A standard container for storing a fixed size sequence of elements.
*
* @ingroup sequences
*
* Meets the requirements of a <a href="tables.html#65">container</a>, a
* <a href="tables.html#66">reversible container</a>, and a
* <a href="tables.html#67">sequence</a>.
*
* Sets support random access iterators.
*
* @tparam Tp Type of element. Required to be a complete type.
* @tparam Nm Number of elements.
*/
template<typename _Tp, std::size_t _Nm>
struct array
{
typedef _Tp value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef value_type* iterator;
typedef const value_type* const_iterator;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// Support for zero-sized arrays mandatory.
typedef _GLIBCXX_STD_C::__array_traits<_Tp, _Nm> _AT_Type;
typename _AT_Type::_Type _M_elems;
// No explicit construct/copy/destroy for aggregate type.
// DR 776.
_GLIBCXX20_CONSTEXPR void
fill(const value_type& __u)
{ std::fill_n(begin(), size(), __u); }
_GLIBCXX20_CONSTEXPR void
swap(array& __other)
noexcept(_AT_Type::_Is_nothrow_swappable::value)
{ std::swap_ranges(begin(), end(), __other.begin()); }
// Iterators.
_GLIBCXX17_CONSTEXPR iterator
begin() noexcept
{ return iterator(data()); }
_GLIBCXX17_CONSTEXPR const_iterator
begin() const noexcept
{ return const_iterator(data()); }
_GLIBCXX17_CONSTEXPR iterator
end() noexcept
{ return iterator(data() + _Nm); }
_GLIBCXX17_CONSTEXPR const_iterator
end() const noexcept
{ return const_iterator(data() + _Nm); }
_GLIBCXX17_CONSTEXPR reverse_iterator
rbegin() noexcept
{ return reverse_iterator(end()); }
_GLIBCXX17_CONSTEXPR const_reverse_iterator
rbegin() const noexcept
{ return const_reverse_iterator(end()); }
_GLIBCXX17_CONSTEXPR reverse_iterator
rend() noexcept
{ return reverse_iterator(begin()); }
_GLIBCXX17_CONSTEXPR const_reverse_iterator
rend() const noexcept
{ return const_reverse_iterator(begin()); }
_GLIBCXX17_CONSTEXPR const_iterator
cbegin() const noexcept
{ return const_iterator(data()); }
_GLIBCXX17_CONSTEXPR const_iterator
cend() const noexcept
{ return const_iterator(data() + _Nm); }
_GLIBCXX17_CONSTEXPR const_reverse_iterator
crbegin() const noexcept
{ return const_reverse_iterator(end()); }
_GLIBCXX17_CONSTEXPR const_reverse_iterator
crend() const noexcept
{ return const_reverse_iterator(begin()); }
// Capacity.
constexpr size_type
size() const noexcept { return _Nm; }
constexpr size_type
max_size() const noexcept { return _Nm; }
_GLIBCXX_NODISCARD constexpr bool
empty() const noexcept { return size() == 0; }
// Element access.
_GLIBCXX17_CONSTEXPR reference
operator[](size_type __n) noexcept
{ return _AT_Type::_S_ref(_M_elems, __n); }
constexpr const_reference
operator[](size_type __n) const noexcept
{ return _AT_Type::_S_ref(_M_elems, __n); }
_GLIBCXX17_CONSTEXPR reference
at(size_type __n)
{
if (__n >= _Nm)
std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
">= _Nm (which is %zu)"),
__n, _Nm);
return _AT_Type::_S_ref(_M_elems, __n);
}
constexpr const_reference
at(size_type __n) const
{
// Result of conditional expression must be an lvalue so use
// boolean ? lvalue : (throw-expr, lvalue)
return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
: (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
">= _Nm (which is %zu)"),
__n, _Nm),
_AT_Type::_S_ref(_M_elems, 0));
}
_GLIBCXX17_CONSTEXPR reference
front() noexcept
{ return *begin(); }
constexpr const_reference
front() const noexcept
{ return _AT_Type::_S_ref(_M_elems, 0); }
_GLIBCXX17_CONSTEXPR reference
back() noexcept
{ return _Nm ? *(end() - 1) : *end(); }
constexpr const_reference
back() const noexcept
{
return _Nm ? _AT_Type::_S_ref(_M_elems, _Nm - 1)
: _AT_Type::_S_ref(_M_elems, 0);
}
_GLIBCXX17_CONSTEXPR pointer
data() noexcept
{ return _AT_Type::_S_ptr(_M_elems); }
_GLIBCXX17_CONSTEXPR const_pointer
data() const noexcept
{ return _AT_Type::_S_ptr(_M_elems); }
};
#if __cpp_deduction_guides >= 201606
template<typename _Tp, typename... _Up>
array(_Tp, _Up...)
-> array<enable_if_t<(is_same_v<_Tp, _Up> && ...), _Tp>,
1 + sizeof...(_Up)>;
#endif
// Array comparisons.
template<typename _Tp, std::size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline bool
operator==(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return std::equal(__one.begin(), __one.end(), __two.begin()); }
#if __cpp_lib_three_way_comparison && __cpp_lib_concepts
template<typename _Tp, size_t _Nm>
constexpr __detail::__synth3way_t<_Tp>
operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
{
#ifdef __cpp_lib_is_constant_evaluated
if constexpr (_Nm && __is_memcmp_ordered<_Tp>::__value)
if (!std::is_constant_evaluated())
{
constexpr size_t __n = _Nm * sizeof(_Tp);
return __builtin_memcmp(__a.data(), __b.data(), __n) <=> 0;
}
#endif
for (size_t __i = 0; __i < _Nm; ++__i)
{
auto __c = __detail::__synth3way(__a[__i], __b[__i]);
if (__c != 0)
return __c;
}
return strong_ordering::equal;
}
#else
template<typename _Tp, std::size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline bool
operator!=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return !(__one == __two); }
template<typename _Tp, std::size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline bool
operator<(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
{
return std::lexicographical_compare(__a.begin(), __a.end(),
__b.begin(), __b.end());
}
template<typename _Tp, std::size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline bool
operator>(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return __two < __one; }
template<typename _Tp, std::size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline bool
operator<=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return !(__one > __two); }
template<typename _Tp, std::size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline bool
operator>=(const array<_Tp, _Nm>& __one, const array<_Tp, _Nm>& __two)
{ return !(__one < __two); }
#endif // three_way_comparison && concepts
// Specialized algorithms.
template<typename _Tp, std::size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
// Constrained free swap overload, see p0185r1
typename enable_if<
_GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value
>::type
#else
void
#endif
swap(array<_Tp, _Nm>& __one, array<_Tp, _Nm>& __two)
noexcept(noexcept(__one.swap(__two)))
{ __one.swap(__two); }
#if __cplusplus > 201402L || !defined(__STRICT_ANSI__) // c++1z or gnu++11
template<typename _Tp, std::size_t _Nm>
typename enable_if<
!_GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::_Is_swappable::value>::type
swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
#endif
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
constexpr _Tp&
get(array<_Tp, _Nm>& __arr) noexcept
{
static_assert(_Int < _Nm, "array index is within bounds");
return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
_S_ref(__arr._M_elems, _Int);
}
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
constexpr _Tp&&
get(array<_Tp, _Nm>&& __arr) noexcept
{
static_assert(_Int < _Nm, "array index is within bounds");
return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
}
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
constexpr const _Tp&
get(const array<_Tp, _Nm>& __arr) noexcept
{
static_assert(_Int < _Nm, "array index is within bounds");
return _GLIBCXX_STD_C::__array_traits<_Tp, _Nm>::
_S_ref(__arr._M_elems, _Int);
}
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
constexpr const _Tp&&
get(const array<_Tp, _Nm>&& __arr) noexcept
{
static_assert(_Int < _Nm, "array index is within bounds");
return std::move(_GLIBCXX_STD_C::get<_Int>(__arr));
}
#if __cplusplus > 201703L
#define __cpp_lib_to_array 201907L
template<bool _Move = false, typename _Tp, size_t... _Idx>
constexpr array<remove_cv_t<_Tp>, sizeof...(_Idx)>
__to_array(_Tp (&__a)[sizeof...(_Idx)], index_sequence<_Idx...>)
{
if constexpr (_Move)
return {{std::move(__a[_Idx])...}};
else
return {{__a[_Idx]...}};
}
template<typename _Tp, size_t _Nm>
constexpr array<remove_cv_t<_Tp>, _Nm>
to_array(_Tp (&__a)[_Nm])
noexcept(is_nothrow_constructible_v<_Tp, _Tp&>)
{
static_assert(!is_array_v<_Tp>);
static_assert(is_constructible_v<_Tp, _Tp&>);
if constexpr (is_constructible_v<_Tp, _Tp&>)
return _GLIBCXX_STD_C::__to_array(__a, make_index_sequence<_Nm>{});
__builtin_unreachable(); // FIXME: see PR c++/91388
}
template<typename _Tp, size_t _Nm>
constexpr array<remove_cv_t<_Tp>, _Nm>
to_array(_Tp (&&__a)[_Nm])
noexcept(is_nothrow_move_constructible_v<_Tp>)
{
static_assert(!is_array_v<_Tp>);
static_assert(is_move_constructible_v<_Tp>);
if constexpr (is_move_constructible_v<_Tp>)
return _GLIBCXX_STD_C::__to_array<1>(__a, make_index_sequence<_Nm>{});
__builtin_unreachable(); // FIXME: see PR c++/91388
}
#endif // C++20
_GLIBCXX_END_NAMESPACE_CONTAINER
} // namespace std
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Tuple interface to class template array.
/// tuple_size
template<typename _Tp>
struct tuple_size;
/// Partial specialization for std::array
template<typename _Tp, std::size_t _Nm>
struct tuple_size<_GLIBCXX_STD_C::array<_Tp, _Nm>>
: public integral_constant<std::size_t, _Nm> { };
/// tuple_element
template<std::size_t _Int, typename _Tp>
struct tuple_element;
/// Partial specialization for std::array
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
struct tuple_element<_Int, _GLIBCXX_STD_C::array<_Tp, _Nm>>
{
static_assert(_Int < _Nm, "index is out of bounds");
typedef _Tp type;
};
template<typename _Tp, std::size_t _Nm>
struct __is_tuple_like_impl<_GLIBCXX_STD_C::array<_Tp, _Nm>> : true_type
{ };
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#ifdef _GLIBCXX_DEBUG
# include <debug/array>
#endif
#endif // C++11
#endif // _GLIBCXX_ARRAY

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,337 @@
// auto_ptr implementation -*- C++ -*-
// Copyright (C) 2007-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file backward/auto_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _BACKWARD_AUTO_PTR_H
#define _BACKWARD_AUTO_PTR_H 1
#include <bits/c++config.h>
#include <debug/debug.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* A wrapper class to provide auto_ptr with reference semantics.
* For example, an auto_ptr can be assigned (or constructed from)
* the result of a function which returns an auto_ptr by value.
*
* All the auto_ptr_ref stuff should happen behind the scenes.
*/
template<typename _Tp1>
struct auto_ptr_ref
{
_Tp1* _M_ptr;
explicit
auto_ptr_ref(_Tp1* __p): _M_ptr(__p) { }
} _GLIBCXX_DEPRECATED;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/**
* @brief A simple smart pointer providing strict ownership semantics.
*
* The Standard says:
* <pre>
* An @c auto_ptr owns the object it holds a pointer to. Copying
* an @c auto_ptr copies the pointer and transfers ownership to the
* destination. If more than one @c auto_ptr owns the same object
* at the same time the behavior of the program is undefined.
*
* The uses of @c auto_ptr include providing temporary
* exception-safety for dynamically allocated memory, passing
* ownership of dynamically allocated memory to a function, and
* returning dynamically allocated memory from a function. @c
* auto_ptr does not meet the CopyConstructible and Assignable
* requirements for Standard Library <a
* href="tables.html#65">container</a> elements and thus
* instantiating a Standard Library container with an @c auto_ptr
* results in undefined behavior.
* </pre>
* Quoted from [20.4.5]/3.
*
* Good examples of what can and cannot be done with auto_ptr can
* be found in the libstdc++ testsuite.
*
* _GLIBCXX_RESOLVE_LIB_DEFECTS
* 127. auto_ptr<> conversion issues
* These resolutions have all been incorporated.
*/
template<typename _Tp>
class auto_ptr
{
private:
_Tp* _M_ptr;
public:
/// The pointed-to type.
typedef _Tp element_type;
/**
* @brief An %auto_ptr is usually constructed from a raw pointer.
* @param __p A pointer (defaults to NULL).
*
* This object now @e owns the object pointed to by @a __p.
*/
explicit
auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
/**
* @brief An %auto_ptr can be constructed from another %auto_ptr.
* @param __a Another %auto_ptr of the same type.
*
* This object now @e owns the object previously owned by @a __a,
* which has given up ownership.
*/
auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { }
/**
* @brief An %auto_ptr can be constructed from another %auto_ptr.
* @param __a Another %auto_ptr of a different but related type.
*
* A pointer-to-Tp1 must be convertible to a
* pointer-to-Tp/element_type.
*
* This object now @e owns the object previously owned by @a __a,
* which has given up ownership.
*/
template<typename _Tp1>
auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { }
/**
* @brief %auto_ptr assignment operator.
* @param __a Another %auto_ptr of the same type.
*
* This object now @e owns the object previously owned by @a __a,
* which has given up ownership. The object that this one @e
* used to own and track has been deleted.
*/
auto_ptr&
operator=(auto_ptr& __a) throw()
{
reset(__a.release());
return *this;
}
/**
* @brief %auto_ptr assignment operator.
* @param __a Another %auto_ptr of a different but related type.
*
* A pointer-to-Tp1 must be convertible to a pointer-to-Tp/element_type.
*
* This object now @e owns the object previously owned by @a __a,
* which has given up ownership. The object that this one @e
* used to own and track has been deleted.
*/
template<typename _Tp1>
auto_ptr&
operator=(auto_ptr<_Tp1>& __a) throw()
{
reset(__a.release());
return *this;
}
/**
* When the %auto_ptr goes out of scope, the object it owns is
* deleted. If it no longer owns anything (i.e., @c get() is
* @c NULL), then this has no effect.
*
* The C++ standard says there is supposed to be an empty throw
* specification here, but omitting it is standard conforming. Its
* presence can be detected only if _Tp::~_Tp() throws, but this is
* prohibited. [17.4.3.6]/2
*/
~auto_ptr() { delete _M_ptr; }
/**
* @brief Smart pointer dereferencing.
*
* If this %auto_ptr no longer owns anything, then this
* operation will crash. (For a smart pointer, <em>no longer owns
* anything</em> is the same as being a null pointer, and you know
* what happens when you dereference one of those...)
*/
element_type&
operator*() const throw()
{
__glibcxx_assert(_M_ptr != 0);
return *_M_ptr;
}
/**
* @brief Smart pointer dereferencing.
*
* This returns the pointer itself, which the language then will
* automatically cause to be dereferenced.
*/
element_type*
operator->() const throw()
{
__glibcxx_assert(_M_ptr != 0);
return _M_ptr;
}
/**
* @brief Bypassing the smart pointer.
* @return The raw pointer being managed.
*
* You can get a copy of the pointer that this object owns, for
* situations such as passing to a function which only accepts
* a raw pointer.
*
* @note This %auto_ptr still owns the memory.
*/
element_type*
get() const throw() { return _M_ptr; }
/**
* @brief Bypassing the smart pointer.
* @return The raw pointer being managed.
*
* You can get a copy of the pointer that this object owns, for
* situations such as passing to a function which only accepts
* a raw pointer.
*
* @note This %auto_ptr no longer owns the memory. When this object
* goes out of scope, nothing will happen.
*/
element_type*
release() throw()
{
element_type* __tmp = _M_ptr;
_M_ptr = 0;
return __tmp;
}
/**
* @brief Forcibly deletes the managed object.
* @param __p A pointer (defaults to NULL).
*
* This object now @e owns the object pointed to by @a __p. The
* previous object has been deleted.
*/
void
reset(element_type* __p = 0) throw()
{
if (__p != _M_ptr)
{
delete _M_ptr;
_M_ptr = __p;
}
}
/**
* @brief Automatic conversions
*
* These operations are supposed to convert an %auto_ptr into and from
* an auto_ptr_ref automatically as needed. This would allow
* constructs such as
* @code
* auto_ptr<Derived> func_returning_auto_ptr(.....);
* ...
* auto_ptr<Base> ptr = func_returning_auto_ptr(.....);
* @endcode
*
* But it doesn't work, and won't be fixed. For further details see
* http://cplusplus.github.io/LWG/lwg-closed.html#463
*/
auto_ptr(auto_ptr_ref<element_type> __ref) throw()
: _M_ptr(__ref._M_ptr) { }
auto_ptr&
operator=(auto_ptr_ref<element_type> __ref) throw()
{
if (__ref._M_ptr != this->get())
{
delete _M_ptr;
_M_ptr = __ref._M_ptr;
}
return *this;
}
template<typename _Tp1>
operator auto_ptr_ref<_Tp1>() throw()
{ return auto_ptr_ref<_Tp1>(this->release()); }
template<typename _Tp1>
operator auto_ptr<_Tp1>() throw()
{ return auto_ptr<_Tp1>(this->release()); }
} _GLIBCXX_DEPRECATED;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 541. shared_ptr template assignment and void
template<>
class auto_ptr<void>
{
public:
typedef void element_type;
} _GLIBCXX_DEPRECATED;
#if __cplusplus >= 201103L
template<_Lock_policy _Lp>
template<typename _Tp>
inline
__shared_count<_Lp>::__shared_count(std::auto_ptr<_Tp>&& __r)
: _M_pi(new _Sp_counted_ptr<_Tp*, _Lp>(__r.get()))
{ __r.release(); }
template<typename _Tp, _Lock_policy _Lp>
template<typename _Tp1, typename>
inline
__shared_ptr<_Tp, _Lp>::__shared_ptr(std::auto_ptr<_Tp1>&& __r)
: _M_ptr(__r.get()), _M_refcount()
{
__glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
static_assert( sizeof(_Tp1) > 0, "incomplete type" );
_Tp1* __tmp = __r.get();
_M_refcount = __shared_count<_Lp>(std::move(__r));
_M_enable_shared_from_this_with(__tmp);
}
template<typename _Tp>
template<typename _Tp1, typename>
inline
shared_ptr<_Tp>::shared_ptr(std::auto_ptr<_Tp1>&& __r)
: __shared_ptr<_Tp>(std::move(__r)) { }
template<typename _Tp, typename _Dp>
template<typename _Up, typename>
inline
unique_ptr<_Tp, _Dp>::unique_ptr(auto_ptr<_Up>&& __u) noexcept
: _M_t(__u.release(), deleter_type()) { }
#endif
#pragma GCC diagnostic pop
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _BACKWARD_AUTO_PTR_H */

View File

@ -0,0 +1,60 @@
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file backward/backward_warning.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _BACKWARD_BACKWARD_WARNING_H
#define _BACKWARD_BACKWARD_WARNING_H 1
#ifdef __DEPRECATED
#warning \
This file includes at least one deprecated or antiquated header which \
may be removed without further notice at a future date. Please use a \
non-deprecated interface with equivalent functionality instead. For a \
listing of replacement headers and interfaces, consult the file \
backward_warning.h. To disable this warning use -Wno-deprecated.
/*
A list of valid replacements is as follows:
Use: Instead of:
<sstream>, basic_stringbuf <strstream>, strstreambuf
<sstream>, basic_istringstream <strstream>, istrstream
<sstream>, basic_ostringstream <strstream>, ostrstream
<sstream>, basic_stringstream <strstream>, strstream
<unordered_set>, unordered_set <ext/hash_set>, hash_set
<unordered_set>, unordered_multiset <ext/hash_set>, hash_multiset
<unordered_map>, unordered_map <ext/hash_map>, hash_map
<unordered_map>, unordered_multimap <ext/hash_map>, hash_multimap
<functional>, bind <functional>, binder1st
<functional>, bind <functional>, binder2nd
<functional>, bind <functional>, bind1st
<functional>, bind <functional>, bind2nd
<memory>, unique_ptr <memory>, auto_ptr
*/
#endif
#endif

View File

@ -0,0 +1,182 @@
// Functor implementations -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996-1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file backward/binders.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _BACKWARD_BINDERS_H
#define _BACKWARD_BINDERS_H 1
// Suppress deprecated warning for this file.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// 20.3.6 binders
/** @defgroup binders Binder Classes
* @ingroup functors
*
* Binders turn functions/functors with two arguments into functors
* with a single argument, storing an argument to be applied later.
* For example, a variable @c B of type @c binder1st is constructed
* from a functor @c f and an argument @c x. Later, B's @c
* operator() is called with a single argument @c y. The return
* value is the value of @c f(x,y). @c B can be @a called with
* various arguments (y1, y2, ...) and will in turn call @c
* f(x,y1), @c f(x,y2), ...
*
* The function @c bind1st is provided to save some typing. It takes the
* function and an argument as parameters, and returns an instance of
* @c binder1st.
*
* The type @c binder2nd and its creator function @c bind2nd do the same
* thing, but the stored argument is passed as the second parameter instead
* of the first, e.g., @c bind2nd(std::minus<float>(),1.3) will create a
* functor whose @c operator() accepts a floating-point number, subtracts
* 1.3 from it, and returns the result. (If @c bind1st had been used,
* the functor would perform <em>1.3 - x</em> instead.
*
* Creator-wrapper functions like @c bind1st are intended to be used in
* calling algorithms. Their return values will be temporary objects.
* (The goal is to not require you to type names like
* @c std::binder1st<std::plus<int>> for declaring a variable to hold the
* return value from @c bind1st(std::plus<int>(),5).
*
* These become more useful when combined with the composition functions.
*
* These functions are deprecated in C++11 and can be replaced by
* @c std::bind (or @c std::tr1::bind) which is more powerful and flexible,
* supporting functions with any number of arguments. Uses of @c bind1st
* can be replaced by @c std::bind(f, x, std::placeholders::_1) and
* @c bind2nd by @c std::bind(f, std::placeholders::_1, x).
* @{
*/
/// One of the @link binders binder functors@endlink.
template<typename _Operation>
class binder1st
: public unary_function<typename _Operation::second_argument_type,
typename _Operation::result_type>
{
protected:
_Operation op;
typename _Operation::first_argument_type value;
public:
binder1st(const _Operation& __x,
const typename _Operation::first_argument_type& __y)
: op(__x), value(__y) { }
typename _Operation::result_type
operator()(const typename _Operation::second_argument_type& __x) const
{ return op(value, __x); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements
typename _Operation::result_type
operator()(typename _Operation::second_argument_type& __x) const
{ return op(value, __x); }
} _GLIBCXX_DEPRECATED;
/// One of the @link binders binder functors@endlink.
template<typename _Operation, typename _Tp>
inline binder1st<_Operation>
bind1st(const _Operation& __fn, const _Tp& __x)
{
typedef typename _Operation::first_argument_type _Arg1_type;
return binder1st<_Operation>(__fn, _Arg1_type(__x));
}
/// One of the @link binders binder functors@endlink.
template<typename _Operation>
class binder2nd
: public unary_function<typename _Operation::first_argument_type,
typename _Operation::result_type>
{
protected:
_Operation op;
typename _Operation::second_argument_type value;
public:
binder2nd(const _Operation& __x,
const typename _Operation::second_argument_type& __y)
: op(__x), value(__y) { }
typename _Operation::result_type
operator()(const typename _Operation::first_argument_type& __x) const
{ return op(__x, value); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 109. Missing binders for non-const sequence elements
typename _Operation::result_type
operator()(typename _Operation::first_argument_type& __x) const
{ return op(__x, value); }
} _GLIBCXX_DEPRECATED;
/// One of the @link binders binder functors@endlink.
template<typename _Operation, typename _Tp>
inline binder2nd<_Operation>
bind2nd(const _Operation& __fn, const _Tp& __x)
{
typedef typename _Operation::second_argument_type _Arg2_type;
return binder2nd<_Operation>(__fn, _Arg2_type(__x));
}
/** @} */
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#pragma GCC diagnostic pop
#endif /* _BACKWARD_BINDERS_H */

View File

@ -0,0 +1,170 @@
// 'struct hash' from SGI -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1996-1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*/
/** @file backward/hash_fun.h
* This file is a GNU extension to the Standard C++ Library (possibly
* containing extensions from the HP/SGI STL subset).
*/
#ifndef _BACKWARD_HASH_FUN_H
#define _BACKWARD_HASH_FUN_H 1
#include <bits/c++config.h>
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
using std::size_t;
template<class _Key>
struct hash { };
inline size_t
__stl_hash_string(const char* __s)
{
unsigned long __h = 0;
for ( ; *__s; ++__s)
__h = 5 * __h + *__s;
return size_t(__h);
}
template<>
struct hash<char*>
{
size_t
operator()(const char* __s) const
{ return __stl_hash_string(__s); }
};
template<>
struct hash<const char*>
{
size_t
operator()(const char* __s) const
{ return __stl_hash_string(__s); }
};
template<>
struct hash<char>
{
size_t
operator()(char __x) const
{ return __x; }
};
template<>
struct hash<unsigned char>
{
size_t
operator()(unsigned char __x) const
{ return __x; }
};
template<>
struct hash<signed char>
{
size_t
operator()(unsigned char __x) const
{ return __x; }
};
template<>
struct hash<short>
{
size_t
operator()(short __x) const
{ return __x; }
};
template<>
struct hash<unsigned short>
{
size_t
operator()(unsigned short __x) const
{ return __x; }
};
template<>
struct hash<int>
{
size_t
operator()(int __x) const
{ return __x; }
};
template<>
struct hash<unsigned int>
{
size_t
operator()(unsigned int __x) const
{ return __x; }
};
template<>
struct hash<long>
{
size_t
operator()(long __x) const
{ return __x; }
};
template<>
struct hash<unsigned long>
{
size_t
operator()(unsigned long __x) const
{ return __x; }
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,599 @@
// Hashing map implementation -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1996
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*/
/** @file backward/hash_map
* This file is a GNU extension to the Standard C++ Library (possibly
* containing extensions from the HP/SGI STL subset).
*/
#ifndef _BACKWARD_HASH_MAP
#define _BACKWARD_HASH_MAP 1
#ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
#include <backward/backward_warning.h>
#endif
#include <bits/c++config.h>
#include <backward/hashtable.h>
#include <bits/concept_check.h>
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
using std::equal_to;
using std::allocator;
using std::pair;
using std::_Select1st;
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<class _Key, class _Tp, class _HashFn = hash<_Key>,
class _EqualKey = equal_to<_Key>, class _Alloc = allocator<_Tp> >
class hash_map
{
private:
typedef hashtable<pair<const _Key, _Tp>,_Key, _HashFn,
_Select1st<pair<const _Key, _Tp> >,
_EqualKey, _Alloc> _Ht;
_Ht _M_ht;
public:
typedef typename _Ht::key_type key_type;
typedef _Tp data_type;
typedef _Tp mapped_type;
typedef typename _Ht::value_type value_type;
typedef typename _Ht::hasher hasher;
typedef typename _Ht::key_equal key_equal;
typedef typename _Ht::size_type size_type;
typedef typename _Ht::difference_type difference_type;
typedef typename _Ht::pointer pointer;
typedef typename _Ht::const_pointer const_pointer;
typedef typename _Ht::reference reference;
typedef typename _Ht::const_reference const_reference;
typedef typename _Ht::iterator iterator;
typedef typename _Ht::const_iterator const_iterator;
typedef typename _Ht::allocator_type allocator_type;
hasher
hash_funct() const
{ return _M_ht.hash_funct(); }
key_equal
key_eq() const
{ return _M_ht.key_eq(); }
allocator_type
get_allocator() const
{ return _M_ht.get_allocator(); }
hash_map()
: _M_ht(100, hasher(), key_equal(), allocator_type()) {}
explicit
hash_map(size_type __n)
: _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
hash_map(size_type __n, const hasher& __hf)
: _M_ht(__n, __hf, key_equal(), allocator_type()) {}
hash_map(size_type __n, const hasher& __hf, const key_equal& __eql,
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a) {}
template<class _InputIterator>
hash_map(_InputIterator __f, _InputIterator __l)
: _M_ht(100, hasher(), key_equal(), allocator_type())
{ _M_ht.insert_unique(__f, __l); }
template<class _InputIterator>
hash_map(_InputIterator __f, _InputIterator __l, size_type __n)
: _M_ht(__n, hasher(), key_equal(), allocator_type())
{ _M_ht.insert_unique(__f, __l); }
template<class _InputIterator>
hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
const hasher& __hf)
: _M_ht(__n, __hf, key_equal(), allocator_type())
{ _M_ht.insert_unique(__f, __l); }
template<class _InputIterator>
hash_map(_InputIterator __f, _InputIterator __l, size_type __n,
const hasher& __hf, const key_equal& __eql,
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a)
{ _M_ht.insert_unique(__f, __l); }
size_type
size() const
{ return _M_ht.size(); }
size_type
max_size() const
{ return _M_ht.max_size(); }
_GLIBCXX_NODISCARD bool
empty() const
{ return _M_ht.empty(); }
void
swap(hash_map& __hs)
{ _M_ht.swap(__hs._M_ht); }
template<class _K1, class _T1, class _HF, class _EqK, class _Al>
friend bool
operator== (const hash_map<_K1, _T1, _HF, _EqK, _Al>&,
const hash_map<_K1, _T1, _HF, _EqK, _Al>&);
iterator
begin()
{ return _M_ht.begin(); }
iterator
end()
{ return _M_ht.end(); }
const_iterator
begin() const
{ return _M_ht.begin(); }
const_iterator
end() const
{ return _M_ht.end(); }
pair<iterator, bool>
insert(const value_type& __obj)
{ return _M_ht.insert_unique(__obj); }
template<class _InputIterator>
void
insert(_InputIterator __f, _InputIterator __l)
{ _M_ht.insert_unique(__f, __l); }
pair<iterator, bool>
insert_noresize(const value_type& __obj)
{ return _M_ht.insert_unique_noresize(__obj); }
iterator
find(const key_type& __key)
{ return _M_ht.find(__key); }
const_iterator
find(const key_type& __key) const
{ return _M_ht.find(__key); }
_Tp&
operator[](const key_type& __key)
{ return _M_ht.find_or_insert(value_type(__key, _Tp())).second; }
size_type
count(const key_type& __key) const
{ return _M_ht.count(__key); }
pair<iterator, iterator>
equal_range(const key_type& __key)
{ return _M_ht.equal_range(__key); }
pair<const_iterator, const_iterator>
equal_range(const key_type& __key) const
{ return _M_ht.equal_range(__key); }
size_type
erase(const key_type& __key)
{return _M_ht.erase(__key); }
void
erase(iterator __it)
{ _M_ht.erase(__it); }
void
erase(iterator __f, iterator __l)
{ _M_ht.erase(__f, __l); }
void
clear()
{ _M_ht.clear(); }
void
resize(size_type __hint)
{ _M_ht.resize(__hint); }
size_type
bucket_count() const
{ return _M_ht.bucket_count(); }
size_type
max_bucket_count() const
{ return _M_ht.max_bucket_count(); }
size_type
elems_in_bucket(size_type __n) const
{ return _M_ht.elems_in_bucket(__n); }
};
template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
inline bool
operator==(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
{ return __hm1._M_ht == __hm2._M_ht; }
template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
inline bool
operator!=(const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
const hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
{ return !(__hm1 == __hm2); }
template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
inline void
swap(hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
hash_map<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
{ __hm1.swap(__hm2); }
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<class _Key, class _Tp,
class _HashFn = hash<_Key>,
class _EqualKey = equal_to<_Key>,
class _Alloc = allocator<_Tp> >
class hash_multimap
{
// concept requirements
__glibcxx_class_requires(_Key, _SGIAssignableConcept)
__glibcxx_class_requires(_Tp, _SGIAssignableConcept)
__glibcxx_class_requires3(_HashFn, size_t, _Key, _UnaryFunctionConcept)
__glibcxx_class_requires3(_EqualKey, _Key, _Key, _BinaryPredicateConcept)
private:
typedef hashtable<pair<const _Key, _Tp>, _Key, _HashFn,
_Select1st<pair<const _Key, _Tp> >, _EqualKey, _Alloc>
_Ht;
_Ht _M_ht;
public:
typedef typename _Ht::key_type key_type;
typedef _Tp data_type;
typedef _Tp mapped_type;
typedef typename _Ht::value_type value_type;
typedef typename _Ht::hasher hasher;
typedef typename _Ht::key_equal key_equal;
typedef typename _Ht::size_type size_type;
typedef typename _Ht::difference_type difference_type;
typedef typename _Ht::pointer pointer;
typedef typename _Ht::const_pointer const_pointer;
typedef typename _Ht::reference reference;
typedef typename _Ht::const_reference const_reference;
typedef typename _Ht::iterator iterator;
typedef typename _Ht::const_iterator const_iterator;
typedef typename _Ht::allocator_type allocator_type;
hasher
hash_funct() const
{ return _M_ht.hash_funct(); }
key_equal
key_eq() const
{ return _M_ht.key_eq(); }
allocator_type
get_allocator() const
{ return _M_ht.get_allocator(); }
hash_multimap()
: _M_ht(100, hasher(), key_equal(), allocator_type()) {}
explicit
hash_multimap(size_type __n)
: _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
hash_multimap(size_type __n, const hasher& __hf)
: _M_ht(__n, __hf, key_equal(), allocator_type()) {}
hash_multimap(size_type __n, const hasher& __hf, const key_equal& __eql,
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a) {}
template<class _InputIterator>
hash_multimap(_InputIterator __f, _InputIterator __l)
: _M_ht(100, hasher(), key_equal(), allocator_type())
{ _M_ht.insert_equal(__f, __l); }
template<class _InputIterator>
hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n)
: _M_ht(__n, hasher(), key_equal(), allocator_type())
{ _M_ht.insert_equal(__f, __l); }
template<class _InputIterator>
hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
const hasher& __hf)
: _M_ht(__n, __hf, key_equal(), allocator_type())
{ _M_ht.insert_equal(__f, __l); }
template<class _InputIterator>
hash_multimap(_InputIterator __f, _InputIterator __l, size_type __n,
const hasher& __hf, const key_equal& __eql,
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a)
{ _M_ht.insert_equal(__f, __l); }
size_type
size() const
{ return _M_ht.size(); }
size_type
max_size() const
{ return _M_ht.max_size(); }
_GLIBCXX_NODISCARD bool
empty() const
{ return _M_ht.empty(); }
void
swap(hash_multimap& __hs)
{ _M_ht.swap(__hs._M_ht); }
template<class _K1, class _T1, class _HF, class _EqK, class _Al>
friend bool
operator==(const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&,
const hash_multimap<_K1, _T1, _HF, _EqK, _Al>&);
iterator
begin()
{ return _M_ht.begin(); }
iterator
end()
{ return _M_ht.end(); }
const_iterator
begin() const
{ return _M_ht.begin(); }
const_iterator
end() const
{ return _M_ht.end(); }
iterator
insert(const value_type& __obj)
{ return _M_ht.insert_equal(__obj); }
template<class _InputIterator>
void
insert(_InputIterator __f, _InputIterator __l)
{ _M_ht.insert_equal(__f,__l); }
iterator
insert_noresize(const value_type& __obj)
{ return _M_ht.insert_equal_noresize(__obj); }
iterator
find(const key_type& __key)
{ return _M_ht.find(__key); }
const_iterator
find(const key_type& __key) const
{ return _M_ht.find(__key); }
size_type
count(const key_type& __key) const
{ return _M_ht.count(__key); }
pair<iterator, iterator>
equal_range(const key_type& __key)
{ return _M_ht.equal_range(__key); }
pair<const_iterator, const_iterator>
equal_range(const key_type& __key) const
{ return _M_ht.equal_range(__key); }
size_type
erase(const key_type& __key)
{ return _M_ht.erase(__key); }
void
erase(iterator __it)
{ _M_ht.erase(__it); }
void
erase(iterator __f, iterator __l)
{ _M_ht.erase(__f, __l); }
void
clear()
{ _M_ht.clear(); }
void
resize(size_type __hint)
{ _M_ht.resize(__hint); }
size_type
bucket_count() const
{ return _M_ht.bucket_count(); }
size_type
max_bucket_count() const
{ return _M_ht.max_bucket_count(); }
size_type
elems_in_bucket(size_type __n) const
{ return _M_ht.elems_in_bucket(__n); }
};
template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
inline bool
operator==(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
{ return __hm1._M_ht == __hm2._M_ht; }
template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc>
inline bool
operator!=(const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1,
const hash_multimap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2)
{ return !(__hm1 == __hm2); }
template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc>
inline void
swap(hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1,
hash_multimap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2)
{ __hm1.swap(__hm2); }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Specialization of insert_iterator so that it will work for hash_map
// and hash_multimap.
template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
class insert_iterator<__gnu_cxx::hash_map<_Key, _Tp, _HashFn,
_EqKey, _Alloc> >
{
protected:
typedef __gnu_cxx::hash_map<_Key, _Tp, _HashFn, _EqKey, _Alloc>
_Container;
_Container* container;
public:
typedef _Container container_type;
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
insert_iterator(_Container& __x)
: container(&__x) {}
insert_iterator(_Container& __x, typename _Container::iterator)
: container(&__x) {}
insert_iterator<_Container>&
operator=(const typename _Container::value_type& __value)
{
container->insert(__value);
return *this;
}
insert_iterator<_Container>&
operator*()
{ return *this; }
insert_iterator<_Container>&
operator++() { return *this; }
insert_iterator<_Container>&
operator++(int)
{ return *this; }
};
template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc>
class insert_iterator<__gnu_cxx::hash_multimap<_Key, _Tp, _HashFn,
_EqKey, _Alloc> >
{
protected:
typedef __gnu_cxx::hash_multimap<_Key, _Tp, _HashFn, _EqKey, _Alloc>
_Container;
_Container* container;
typename _Container::iterator iter;
public:
typedef _Container container_type;
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
insert_iterator(_Container& __x)
: container(&__x) {}
insert_iterator(_Container& __x, typename _Container::iterator)
: container(&__x) {}
insert_iterator<_Container>&
operator=(const typename _Container::value_type& __value)
{
container->insert(__value);
return *this;
}
insert_iterator<_Container>&
operator*()
{ return *this; }
insert_iterator<_Container>&
operator++()
{ return *this; }
insert_iterator<_Container>&
operator++(int)
{ return *this; }
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,569 @@
// Hashing set implementation -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1996
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*/
/** @file backward/hash_set
* This file is a GNU extension to the Standard C++ Library (possibly
* containing extensions from the HP/SGI STL subset).
*/
#ifndef _BACKWARD_HASH_SET
#define _BACKWARD_HASH_SET 1
#ifndef _GLIBCXX_PERMIT_BACKWARD_HASH
#include <backward/backward_warning.h>
#endif
#include <bits/c++config.h>
#include <backward/hashtable.h>
#include <bits/concept_check.h>
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
using std::equal_to;
using std::allocator;
using std::pair;
using std::_Identity;
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<class _Value, class _HashFcn = hash<_Value>,
class _EqualKey = equal_to<_Value>,
class _Alloc = allocator<_Value> >
class hash_set
{
// concept requirements
__glibcxx_class_requires(_Value, _SGIAssignableConcept)
__glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
__glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
typedef __alloc_traits<_Alloc> _Alloc_traits;
private:
typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
_EqualKey, _Alloc> _Ht;
_Ht _M_ht;
public:
typedef typename _Ht::key_type key_type;
typedef typename _Ht::value_type value_type;
typedef typename _Ht::hasher hasher;
typedef typename _Ht::key_equal key_equal;
typedef typename _Ht::size_type size_type;
typedef typename _Ht::difference_type difference_type;
typedef typename _Alloc_traits::pointer pointer;
typedef typename _Alloc_traits::const_pointer const_pointer;
typedef typename _Alloc_traits::reference reference;
typedef typename _Alloc_traits::const_reference const_reference;
typedef typename _Ht::const_iterator iterator;
typedef typename _Ht::const_iterator const_iterator;
typedef typename _Ht::allocator_type allocator_type;
hasher
hash_funct() const
{ return _M_ht.hash_funct(); }
key_equal
key_eq() const
{ return _M_ht.key_eq(); }
allocator_type
get_allocator() const
{ return _M_ht.get_allocator(); }
hash_set()
: _M_ht(100, hasher(), key_equal(), allocator_type()) {}
explicit
hash_set(size_type __n)
: _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
hash_set(size_type __n, const hasher& __hf)
: _M_ht(__n, __hf, key_equal(), allocator_type()) {}
hash_set(size_type __n, const hasher& __hf, const key_equal& __eql,
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a) {}
template<class _InputIterator>
hash_set(_InputIterator __f, _InputIterator __l)
: _M_ht(100, hasher(), key_equal(), allocator_type())
{ _M_ht.insert_unique(__f, __l); }
template<class _InputIterator>
hash_set(_InputIterator __f, _InputIterator __l, size_type __n)
: _M_ht(__n, hasher(), key_equal(), allocator_type())
{ _M_ht.insert_unique(__f, __l); }
template<class _InputIterator>
hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
const hasher& __hf)
: _M_ht(__n, __hf, key_equal(), allocator_type())
{ _M_ht.insert_unique(__f, __l); }
template<class _InputIterator>
hash_set(_InputIterator __f, _InputIterator __l, size_type __n,
const hasher& __hf, const key_equal& __eql,
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a)
{ _M_ht.insert_unique(__f, __l); }
size_type
size() const
{ return _M_ht.size(); }
size_type
max_size() const
{ return _M_ht.max_size(); }
_GLIBCXX_NODISCARD bool
empty() const
{ return _M_ht.empty(); }
void
swap(hash_set& __hs)
{ _M_ht.swap(__hs._M_ht); }
template<class _Val, class _HF, class _EqK, class _Al>
friend bool
operator==(const hash_set<_Val, _HF, _EqK, _Al>&,
const hash_set<_Val, _HF, _EqK, _Al>&);
iterator
begin() const
{ return _M_ht.begin(); }
iterator
end() const
{ return _M_ht.end(); }
pair<iterator, bool>
insert(const value_type& __obj)
{
pair<typename _Ht::iterator, bool> __p = _M_ht.insert_unique(__obj);
return pair<iterator,bool>(__p.first, __p.second);
}
template<class _InputIterator>
void
insert(_InputIterator __f, _InputIterator __l)
{ _M_ht.insert_unique(__f, __l); }
pair<iterator, bool>
insert_noresize(const value_type& __obj)
{
pair<typename _Ht::iterator, bool> __p
= _M_ht.insert_unique_noresize(__obj);
return pair<iterator, bool>(__p.first, __p.second);
}
iterator
find(const key_type& __key) const
{ return _M_ht.find(__key); }
size_type
count(const key_type& __key) const
{ return _M_ht.count(__key); }
pair<iterator, iterator>
equal_range(const key_type& __key) const
{ return _M_ht.equal_range(__key); }
size_type
erase(const key_type& __key)
{return _M_ht.erase(__key); }
void
erase(iterator __it)
{ _M_ht.erase(__it); }
void
erase(iterator __f, iterator __l)
{ _M_ht.erase(__f, __l); }
void
clear()
{ _M_ht.clear(); }
void
resize(size_type __hint)
{ _M_ht.resize(__hint); }
size_type
bucket_count() const
{ return _M_ht.bucket_count(); }
size_type
max_bucket_count() const
{ return _M_ht.max_bucket_count(); }
size_type
elems_in_bucket(size_type __n) const
{ return _M_ht.elems_in_bucket(__n); }
};
template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
inline bool
operator==(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
{ return __hs1._M_ht == __hs2._M_ht; }
template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
inline bool
operator!=(const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs1,
const hash_set<_Value, _HashFcn, _EqualKey, _Alloc>& __hs2)
{ return !(__hs1 == __hs2); }
template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
inline void
swap(hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
hash_set<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
{ __hs1.swap(__hs2); }
/**
* This is an SGI extension.
* @ingroup SGIextensions
* @doctodo
*/
template<class _Value,
class _HashFcn = hash<_Value>,
class _EqualKey = equal_to<_Value>,
class _Alloc = allocator<_Value> >
class hash_multiset
{
// concept requirements
__glibcxx_class_requires(_Value, _SGIAssignableConcept)
__glibcxx_class_requires3(_HashFcn, size_t, _Value, _UnaryFunctionConcept)
__glibcxx_class_requires3(_EqualKey, _Value, _Value, _BinaryPredicateConcept)
private:
typedef hashtable<_Value, _Value, _HashFcn, _Identity<_Value>,
_EqualKey, _Alloc> _Ht;
_Ht _M_ht;
public:
typedef typename _Ht::key_type key_type;
typedef typename _Ht::value_type value_type;
typedef typename _Ht::hasher hasher;
typedef typename _Ht::key_equal key_equal;
typedef typename _Ht::size_type size_type;
typedef typename _Ht::difference_type difference_type;
typedef typename _Alloc::pointer pointer;
typedef typename _Alloc::const_pointer const_pointer;
typedef typename _Alloc::reference reference;
typedef typename _Alloc::const_reference const_reference;
typedef typename _Ht::const_iterator iterator;
typedef typename _Ht::const_iterator const_iterator;
typedef typename _Ht::allocator_type allocator_type;
hasher
hash_funct() const
{ return _M_ht.hash_funct(); }
key_equal
key_eq() const
{ return _M_ht.key_eq(); }
allocator_type
get_allocator() const
{ return _M_ht.get_allocator(); }
hash_multiset()
: _M_ht(100, hasher(), key_equal(), allocator_type()) {}
explicit
hash_multiset(size_type __n)
: _M_ht(__n, hasher(), key_equal(), allocator_type()) {}
hash_multiset(size_type __n, const hasher& __hf)
: _M_ht(__n, __hf, key_equal(), allocator_type()) {}
hash_multiset(size_type __n, const hasher& __hf, const key_equal& __eql,
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a) {}
template<class _InputIterator>
hash_multiset(_InputIterator __f, _InputIterator __l)
: _M_ht(100, hasher(), key_equal(), allocator_type())
{ _M_ht.insert_equal(__f, __l); }
template<class _InputIterator>
hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n)
: _M_ht(__n, hasher(), key_equal(), allocator_type())
{ _M_ht.insert_equal(__f, __l); }
template<class _InputIterator>
hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
const hasher& __hf)
: _M_ht(__n, __hf, key_equal(), allocator_type())
{ _M_ht.insert_equal(__f, __l); }
template<class _InputIterator>
hash_multiset(_InputIterator __f, _InputIterator __l, size_type __n,
const hasher& __hf, const key_equal& __eql,
const allocator_type& __a = allocator_type())
: _M_ht(__n, __hf, __eql, __a)
{ _M_ht.insert_equal(__f, __l); }
size_type
size() const
{ return _M_ht.size(); }
size_type
max_size() const
{ return _M_ht.max_size(); }
_GLIBCXX_NODISCARD bool
empty() const
{ return _M_ht.empty(); }
void
swap(hash_multiset& hs)
{ _M_ht.swap(hs._M_ht); }
template<class _Val, class _HF, class _EqK, class _Al>
friend bool
operator==(const hash_multiset<_Val, _HF, _EqK, _Al>&,
const hash_multiset<_Val, _HF, _EqK, _Al>&);
iterator
begin() const
{ return _M_ht.begin(); }
iterator
end() const
{ return _M_ht.end(); }
iterator
insert(const value_type& __obj)
{ return _M_ht.insert_equal(__obj); }
template<class _InputIterator>
void
insert(_InputIterator __f, _InputIterator __l)
{ _M_ht.insert_equal(__f,__l); }
iterator
insert_noresize(const value_type& __obj)
{ return _M_ht.insert_equal_noresize(__obj); }
iterator
find(const key_type& __key) const
{ return _M_ht.find(__key); }
size_type
count(const key_type& __key) const
{ return _M_ht.count(__key); }
pair<iterator, iterator>
equal_range(const key_type& __key) const
{ return _M_ht.equal_range(__key); }
size_type
erase(const key_type& __key)
{ return _M_ht.erase(__key); }
void
erase(iterator __it)
{ _M_ht.erase(__it); }
void
erase(iterator __f, iterator __l)
{ _M_ht.erase(__f, __l); }
void
clear()
{ _M_ht.clear(); }
void
resize(size_type __hint)
{ _M_ht.resize(__hint); }
size_type
bucket_count() const
{ return _M_ht.bucket_count(); }
size_type
max_bucket_count() const
{ return _M_ht.max_bucket_count(); }
size_type
elems_in_bucket(size_type __n) const
{ return _M_ht.elems_in_bucket(__n); }
};
template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
inline bool
operator==(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
{ return __hs1._M_ht == __hs2._M_ht; }
template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
inline bool
operator!=(const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
const hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
{ return !(__hs1 == __hs2); }
template<class _Val, class _HashFcn, class _EqualKey, class _Alloc>
inline void
swap(hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs1,
hash_multiset<_Val, _HashFcn, _EqualKey, _Alloc>& __hs2)
{ __hs1.swap(__hs2); }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Specialization of insert_iterator so that it will work for hash_set
// and hash_multiset.
template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
class insert_iterator<__gnu_cxx::hash_set<_Value, _HashFcn,
_EqualKey, _Alloc> >
{
protected:
typedef __gnu_cxx::hash_set<_Value, _HashFcn, _EqualKey, _Alloc>
_Container;
_Container* container;
public:
typedef _Container container_type;
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
insert_iterator(_Container& __x)
: container(&__x) {}
insert_iterator(_Container& __x, typename _Container::iterator)
: container(&__x) {}
insert_iterator<_Container>&
operator=(const typename _Container::value_type& __value)
{
container->insert(__value);
return *this;
}
insert_iterator<_Container>&
operator*()
{ return *this; }
insert_iterator<_Container>&
operator++()
{ return *this; }
insert_iterator<_Container>&
operator++(int)
{ return *this; }
};
template<class _Value, class _HashFcn, class _EqualKey, class _Alloc>
class insert_iterator<__gnu_cxx::hash_multiset<_Value, _HashFcn,
_EqualKey, _Alloc> >
{
protected:
typedef __gnu_cxx::hash_multiset<_Value, _HashFcn, _EqualKey, _Alloc>
_Container;
_Container* container;
typename _Container::iterator iter;
public:
typedef _Container container_type;
typedef output_iterator_tag iterator_category;
typedef void value_type;
typedef void difference_type;
typedef void pointer;
typedef void reference;
insert_iterator(_Container& __x)
: container(&__x) {}
insert_iterator(_Container& __x, typename _Container::iterator)
: container(&__x) {}
insert_iterator<_Container>&
operator=(const typename _Container::value_type& __value)
{
container->insert(__value);
return *this;
}
insert_iterator<_Container>&
operator*()
{ return *this; }
insert_iterator<_Container>&
operator++()
{ return *this; }
insert_iterator<_Container>&
operator++(int) { return *this; }
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,239 @@
// Backward-compat support -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
// WARNING: The classes defined in this header are DEPRECATED. This
// header is defined in section D.7.1 of the C++ standard, and it
// MAY BE REMOVED in a future standard revision. One should use the
// header <sstream> instead.
/** @file strstream
* This is a Standard C++ Library header.
*/
#ifndef _BACKWARD_STRSTREAM
#define _BACKWARD_STRSTREAM
#include <backward/backward_warning.h>
#include <iosfwd>
#include <ios>
#include <istream>
#include <ostream>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Class strstreambuf, a streambuf class that manages an array of char.
// Note that this class is not a template.
class strstreambuf : public basic_streambuf<char, char_traits<char> >
{
public:
// Types.
typedef char_traits<char> _Traits;
typedef basic_streambuf<char, _Traits> _Base;
public:
// Constructor, destructor
#if __cplusplus >= 201103L
strstreambuf() : strstreambuf(0) { }
explicit strstreambuf(streamsize __initial_capacity);
#else
explicit strstreambuf(streamsize __initial_capacity = 0);
#endif
strstreambuf(void* (*__alloc)(size_t), void (*__free)(void*));
strstreambuf(char* __get, streamsize __n, char* __put = 0) throw ();
strstreambuf(signed char* __get, streamsize __n, signed char* __put = 0) throw ();
strstreambuf(unsigned char* __get, streamsize __n, unsigned char* __put=0) throw ();
strstreambuf(const char* __get, streamsize __n) throw ();
strstreambuf(const signed char* __get, streamsize __n) throw ();
strstreambuf(const unsigned char* __get, streamsize __n) throw ();
virtual ~strstreambuf();
#if __cplusplus >= 201103L
strstreambuf(strstreambuf&& __rhs) noexcept
: _Base(__rhs), _M_alloc_fun(__rhs._M_alloc_fun),
_M_free_fun(__rhs._M_free_fun), _M_dynamic(__rhs._M_dynamic),
_M_frozen(__rhs._M_frozen), _M_constant(__rhs._M_constant)
{
__rhs.setg(nullptr, nullptr, nullptr);
__rhs.setp(nullptr, nullptr);
}
strstreambuf&
operator=(strstreambuf&& __rhs) noexcept
{
if (_M_dynamic && !_M_frozen)
_M_free(eback());
_Base::operator=(static_cast<const _Base&>(__rhs));
_M_alloc_fun = __rhs._M_alloc_fun;
_M_free_fun = __rhs._M_free_fun;
_M_dynamic = __rhs._M_dynamic;
_M_frozen = __rhs._M_frozen;
_M_constant = __rhs._M_constant;
__rhs.setg(nullptr, nullptr, nullptr);
__rhs.setp(nullptr, nullptr);
return *this;
}
#endif
public:
void freeze(bool = true) throw ();
char* str() throw ();
_GLIBCXX_PURE int pcount() const throw ();
protected:
virtual int_type overflow(int_type __c = _Traits::eof());
virtual int_type pbackfail(int_type __c = _Traits::eof());
virtual int_type underflow();
virtual _Base* setbuf(char* __buf, streamsize __n);
virtual pos_type seekoff(off_type __off, ios_base::seekdir __dir,
ios_base::openmode __mode
= ios_base::in | ios_base::out);
virtual pos_type seekpos(pos_type __pos, ios_base::openmode __mode
= ios_base::in | ios_base::out);
private:
#if __cplusplus < 201103L
strstreambuf&
operator=(const strstreambuf&);
strstreambuf(const strstreambuf&);
#endif
// Dynamic allocation, possibly using _M_alloc_fun and _M_free_fun.
char* _M_alloc(size_t);
void _M_free(char*);
// Helper function used in constructors.
void _M_setup(char* __get, char* __put, streamsize __n) throw ();
// Data members.
void* (*_M_alloc_fun)(size_t);
void (*_M_free_fun)(void*);
bool _M_dynamic : 1;
bool _M_frozen : 1;
bool _M_constant : 1;
};
// Class istrstream, an istream that manages a strstreambuf.
class istrstream : public basic_istream<char>
{
public:
explicit istrstream(char*);
explicit istrstream(const char*);
istrstream(char* , streamsize);
istrstream(const char*, streamsize);
virtual ~istrstream();
#if __cplusplus >= 201103L
istrstream(istrstream&& __rhs)
: istream(std::move(__rhs)), _M_buf(std::move(__rhs._M_buf))
{ set_rdbuf(&_M_buf); }
istrstream& operator=(istrstream&&) = default;
#endif
_GLIBCXX_CONST strstreambuf* rdbuf() const throw ();
char* str() throw ();
private:
strstreambuf _M_buf;
};
// Class ostrstream
class ostrstream : public basic_ostream<char>
{
public:
ostrstream();
ostrstream(char*, int, ios_base::openmode = ios_base::out);
virtual ~ostrstream();
#if __cplusplus >= 201103L
ostrstream(ostrstream&& __rhs)
: ostream(std::move(__rhs)), _M_buf(std::move(__rhs._M_buf))
{ set_rdbuf(&_M_buf); }
ostrstream& operator=(ostrstream&&) = default;
#endif
_GLIBCXX_CONST strstreambuf* rdbuf() const throw ();
void freeze(bool = true) throw();
char* str() throw ();
_GLIBCXX_PURE int pcount() const throw ();
private:
strstreambuf _M_buf;
};
// Class strstream
class strstream : public basic_iostream<char>
{
public:
typedef char char_type;
typedef char_traits<char>::int_type int_type;
typedef char_traits<char>::pos_type pos_type;
typedef char_traits<char>::off_type off_type;
strstream();
strstream(char*, int, ios_base::openmode = ios_base::in | ios_base::out);
virtual ~strstream();
#if __cplusplus >= 201103L
strstream(strstream&& __rhs)
: iostream(std::move(__rhs)), _M_buf(std::move(__rhs._M_buf))
{ set_rdbuf(&_M_buf); }
strstream& operator=(strstream&&) = default;
#endif
_GLIBCXX_CONST strstreambuf* rdbuf() const throw ();
void freeze(bool = true) throw ();
_GLIBCXX_PURE int pcount() const throw ();
char* str() throw ();
private:
strstreambuf _M_buf;
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,380 @@
// <bit> -*- C++ -*-
// Copyright (C) 2018-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bit
* This is a Standard C++ Library header.
*/
#ifndef _GLIBCXX_BIT
#define _GLIBCXX_BIT 1
#pragma GCC system_header
#if __cplusplus >= 201402L
#include <type_traits>
#if _GLIBCXX_HOSTED
# include <ext/numeric_traits.h>
#else
# include <limits>
/// @cond undocumented
namespace __gnu_cxx
{
template<typename _Tp>
struct __int_traits
{
static constexpr int __digits = std::numeric_limits<_Tp>::digits;
static constexpr _Tp __max = std::numeric_limits<_Tp>::max();
};
}
/// @endcond
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @defgroup bit_manip Bit manipulation
* @ingroup numerics
*
* Utilities for examining and manipulating individual bits.
*
* @{
*/
/// @cond undoc
template<typename _Tp>
constexpr _Tp
__rotl(_Tp __x, int __s) noexcept
{
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
const int __r = __s % _Nd;
if (__r == 0)
return __x;
else if (__r > 0)
return (__x << __r) | (__x >> ((_Nd - __r) % _Nd));
else
return (__x >> -__r) | (__x << ((_Nd + __r) % _Nd)); // rotr(x, -r)
}
template<typename _Tp>
constexpr _Tp
__rotr(_Tp __x, int __s) noexcept
{
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
const int __r = __s % _Nd;
if (__r == 0)
return __x;
else if (__r > 0)
return (__x >> __r) | (__x << ((_Nd - __r) % _Nd));
else
return (__x << -__r) | (__x >> ((_Nd + __r) % _Nd)); // rotl(x, -r)
}
template<typename _Tp>
constexpr int
__countl_zero(_Tp __x) noexcept
{
using __gnu_cxx::__int_traits;
constexpr auto _Nd = __int_traits<_Tp>::__digits;
if (__x == 0)
return _Nd;
constexpr auto _Nd_ull = __int_traits<unsigned long long>::__digits;
constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits;
constexpr auto _Nd_u = __int_traits<unsigned>::__digits;
if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
{
constexpr int __diff = _Nd_u - _Nd;
return __builtin_clz(__x) - __diff;
}
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
{
constexpr int __diff = _Nd_ul - _Nd;
return __builtin_clzl(__x) - __diff;
}
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
{
constexpr int __diff = _Nd_ull - _Nd;
return __builtin_clzll(__x) - __diff;
}
else // (_Nd > _Nd_ull)
{
static_assert(_Nd <= (2 * _Nd_ull),
"Maximum supported integer size is 128-bit");
unsigned long long __high = __x >> _Nd_ull;
if (__high != 0)
{
constexpr int __diff = (2 * _Nd_ull) - _Nd;
return __builtin_clzll(__high) - __diff;
}
constexpr auto __max_ull = __int_traits<unsigned long long>::__max;
unsigned long long __low = __x & __max_ull;
return (_Nd - _Nd_ull) + __builtin_clzll(__low);
}
}
template<typename _Tp>
constexpr int
__countl_one(_Tp __x) noexcept
{
return std::__countl_zero<_Tp>((_Tp)~__x);
}
template<typename _Tp>
constexpr int
__countr_zero(_Tp __x) noexcept
{
using __gnu_cxx::__int_traits;
constexpr auto _Nd = __int_traits<_Tp>::__digits;
if (__x == 0)
return _Nd;
constexpr auto _Nd_ull = __int_traits<unsigned long long>::__digits;
constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits;
constexpr auto _Nd_u = __int_traits<unsigned>::__digits;
if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
return __builtin_ctz(__x);
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
return __builtin_ctzl(__x);
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
return __builtin_ctzll(__x);
else // (_Nd > _Nd_ull)
{
static_assert(_Nd <= (2 * _Nd_ull),
"Maximum supported integer size is 128-bit");
constexpr auto __max_ull = __int_traits<unsigned long long>::__max;
unsigned long long __low = __x & __max_ull;
if (__low != 0)
return __builtin_ctzll(__low);
unsigned long long __high = __x >> _Nd_ull;
return __builtin_ctzll(__high) + _Nd_ull;
}
}
template<typename _Tp>
constexpr int
__countr_one(_Tp __x) noexcept
{
return std::__countr_zero((_Tp)~__x);
}
template<typename _Tp>
constexpr int
__popcount(_Tp __x) noexcept
{
using __gnu_cxx::__int_traits;
constexpr auto _Nd = __int_traits<_Tp>::__digits;
constexpr auto _Nd_ull = __int_traits<unsigned long long>::__digits;
constexpr auto _Nd_ul = __int_traits<unsigned long>::__digits;
constexpr auto _Nd_u = __int_traits<unsigned>::__digits;
if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_u)
return __builtin_popcount(__x);
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ul)
return __builtin_popcountl(__x);
else if _GLIBCXX17_CONSTEXPR (_Nd <= _Nd_ull)
return __builtin_popcountll(__x);
else // (_Nd > _Nd_ull)
{
static_assert(_Nd <= (2 * _Nd_ull),
"Maximum supported integer size is 128-bit");
constexpr auto __max_ull = __int_traits<unsigned long long>::__max;
unsigned long long __low = __x & __max_ull;
unsigned long long __high = __x >> _Nd_ull;
return __builtin_popcountll(__low) + __builtin_popcountll(__high);
}
}
template<typename _Tp>
constexpr bool
__has_single_bit(_Tp __x) noexcept
{ return std::__popcount(__x) == 1; }
template<typename _Tp>
constexpr _Tp
__bit_ceil(_Tp __x) noexcept
{
using __gnu_cxx::__int_traits;
constexpr auto _Nd = __int_traits<_Tp>::__digits;
if (__x == 0 || __x == 1)
return 1;
auto __shift_exponent = _Nd - std::__countl_zero((_Tp)(__x - 1u));
// If the shift exponent equals _Nd then the correct result is not
// representable as a value of _Tp, and so the result is undefined.
// Want that undefined behaviour to be detected in constant expressions,
// by UBSan, and by debug assertions.
#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
if (!__builtin_is_constant_evaluated())
{
__glibcxx_assert( __shift_exponent != __int_traits<_Tp>::__digits );
}
#endif
using __promoted_type = decltype(__x << 1);
if _GLIBCXX17_CONSTEXPR (!is_same<__promoted_type, _Tp>::value)
{
// If __x undergoes integral promotion then shifting by _Nd is
// not undefined. In order to make the shift undefined, so that
// it is diagnosed in constant expressions and by UBsan, we also
// need to "promote" the shift exponent to be too large for the
// promoted type.
const int __extra_exp = sizeof(__promoted_type) / sizeof(_Tp) / 2;
__shift_exponent |= (__shift_exponent & _Nd) << __extra_exp;
}
return (_Tp)1u << __shift_exponent;
}
template<typename _Tp>
constexpr _Tp
__bit_floor(_Tp __x) noexcept
{
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
if (__x == 0)
return 0;
return (_Tp)1u << (_Nd - std::__countl_zero((_Tp)(__x >> 1)));
}
template<typename _Tp>
constexpr _Tp
__bit_width(_Tp __x) noexcept
{
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
return _Nd - std::__countl_zero(__x);
}
/// @endcond
#if __cplusplus > 201703L
#define __cpp_lib_bitops 201907L
/// @cond undoc
template<typename _Tp, typename _Up = _Tp>
using _If_is_unsigned_integer
= enable_if_t<__is_unsigned_integer<_Tp>::value, _Up>;
/// @endcond
// [bit.rot], rotating
/// Rotate `x` to the left by `s` bits.
template<typename _Tp>
[[nodiscard]] constexpr _If_is_unsigned_integer<_Tp>
rotl(_Tp __x, int __s) noexcept
{ return std::__rotl(__x, __s); }
/// Rotate `x` to the right by `s` bits.
template<typename _Tp>
[[nodiscard]] constexpr _If_is_unsigned_integer<_Tp>
rotr(_Tp __x, int __s) noexcept
{ return std::__rotr(__x, __s); }
// [bit.count], counting
/// The number of contiguous zero bits, starting from the highest bit.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
countl_zero(_Tp __x) noexcept
{ return std::__countl_zero(__x); }
/// The number of contiguous one bits, starting from the highest bit.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
countl_one(_Tp __x) noexcept
{ return std::__countl_one(__x); }
/// The number of contiguous zero bits, starting from the lowest bit.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
countr_zero(_Tp __x) noexcept
{ return std::__countr_zero(__x); }
/// The number of contiguous one bits, starting from the lowest bit.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
countr_one(_Tp __x) noexcept
{ return std::__countr_one(__x); }
/// The number of bits set in `x`.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, int>
popcount(_Tp __x) noexcept
{ return std::__popcount(__x); }
// [bit.pow.two], integral powers of 2
#define __cpp_lib_int_pow2 202002L
/// True if `x` is a power of two, false otherwise.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp, bool>
has_single_bit(_Tp __x) noexcept
{ return std::__has_single_bit(__x); }
/// The smallest power-of-two not less than `x`.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp>
bit_ceil(_Tp __x) noexcept
{ return std::__bit_ceil(__x); }
/// The largest power-of-two not greater than `x`.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp>
bit_floor(_Tp __x) noexcept
{ return std::__bit_floor(__x); }
/// The smallest integer greater than the base-2 logarithm of `x`.
template<typename _Tp>
constexpr _If_is_unsigned_integer<_Tp>
bit_width(_Tp __x) noexcept
{ return std::__bit_width(__x); }
#define __cpp_lib_endian 201907L
/// Byte order
enum class endian
{
little = __ORDER_LITTLE_ENDIAN__,
big = __ORDER_BIG_ENDIAN__,
native = __BYTE_ORDER__
};
#endif // C++2a
/// @}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++14
#endif // _GLIBCXX_BIT

View File

@ -0,0 +1,967 @@
// <algorithm> Forward declarations -*- C++ -*-
// Copyright (C) 2007-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/algorithmfwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{algorithm}
*/
#ifndef _GLIBCXX_ALGORITHMFWD_H
#define _GLIBCXX_ALGORITHMFWD_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stl_pair.h>
#include <bits/stl_iterator_base_types.h>
#if __cplusplus >= 201103L
#include <initializer_list>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/*
adjacent_find
all_of (C++11)
any_of (C++11)
binary_search
clamp (C++17)
copy
copy_backward
copy_if (C++11)
copy_n (C++11)
count
count_if
equal
equal_range
fill
fill_n
find
find_end
find_first_of
find_if
find_if_not (C++11)
for_each
generate
generate_n
includes
inplace_merge
is_heap (C++11)
is_heap_until (C++11)
is_partitioned (C++11)
is_sorted (C++11)
is_sorted_until (C++11)
iter_swap
lexicographical_compare
lower_bound
make_heap
max
max_element
merge
min
min_element
minmax (C++11)
minmax_element (C++11)
mismatch
next_permutation
none_of (C++11)
nth_element
partial_sort
partial_sort_copy
partition
partition_copy (C++11)
partition_point (C++11)
pop_heap
prev_permutation
push_heap
random_shuffle
remove
remove_copy
remove_copy_if
remove_if
replace
replace_copy
replace_copy_if
replace_if
reverse
reverse_copy
rotate
rotate_copy
search
search_n
set_difference
set_intersection
set_symmetric_difference
set_union
shuffle (C++11)
sort
sort_heap
stable_partition
stable_sort
swap
swap_ranges
transform
unique
unique_copy
upper_bound
*/
/**
* @defgroup algorithms Algorithms
*
* Components for performing algorithmic operations. Includes
* non-modifying sequence, modifying (mutating) sequence, sorting,
* searching, merge, partition, heap, set, minima, maxima, and
* permutation operations.
*/
/**
* @defgroup mutating_algorithms Mutating
* @ingroup algorithms
*/
/**
* @defgroup non_mutating_algorithms Non-Mutating
* @ingroup algorithms
*/
/**
* @defgroup sorting_algorithms Sorting
* @ingroup algorithms
*/
/**
* @defgroup set_algorithms Set Operations
* @ingroup sorting_algorithms
*
* These algorithms are common set operations performed on sequences
* that are already sorted. The number of comparisons will be
* linear.
*/
/**
* @defgroup binary_search_algorithms Binary Search
* @ingroup sorting_algorithms
*
* These algorithms are variations of a classic binary search, and
* all assume that the sequence being searched is already sorted.
*
* The number of comparisons will be logarithmic (and as few as
* possible). The number of steps through the sequence will be
* logarithmic for random-access iterators (e.g., pointers), and
* linear otherwise.
*
* The LWG has passed Defect Report 270, which notes: <em>The
* proposed resolution reinterprets binary search. Instead of
* thinking about searching for a value in a sorted range, we view
* that as an important special case of a more general algorithm:
* searching for the partition point in a partitioned range. We
* also add a guarantee that the old wording did not: we ensure that
* the upper bound is no earlier than the lower bound, that the pair
* returned by equal_range is a valid range, and that the first part
* of that pair is the lower bound.</em>
*
* The actual effect of the first sentence is that a comparison
* functor passed by the user doesn't necessarily need to induce a
* strict weak ordering relation. Rather, it partitions the range.
*/
// adjacent_find
#if __cplusplus > 201703L
# define __cpp_lib_constexpr_algorithms 201806L
#endif
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
all_of(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
any_of(_IIter, _IIter, _Predicate);
#endif
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
binary_search(_FIter, _FIter, const _Tp&, _Compare);
#if __cplusplus > 201402L
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
const _Tp&
clamp(const _Tp&, const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
const _Tp&
clamp(const _Tp&, const _Tp&, const _Tp&, _Compare);
#endif
template<typename _IIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
copy(_IIter, _IIter, _OIter);
template<typename _BIter1, typename _BIter2>
_GLIBCXX20_CONSTEXPR
_BIter2
copy_backward(_BIter1, _BIter1, _BIter2);
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_OIter
copy_if(_IIter, _IIter, _OIter, _Predicate);
template<typename _IIter, typename _Size, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
copy_n(_IIter, _Size, _OIter);
#endif
// count
// count_if
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
pair<_FIter, _FIter>
equal_range(_FIter, _FIter, const _Tp&, _Compare);
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
fill(_FIter, _FIter, const _Tp&);
template<typename _OIter, typename _Size, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
fill_n(_OIter, _Size, const _Tp&);
// find
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter1
find_end(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
// find_first_of
// find_if
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_IIter
find_if_not(_IIter, _IIter, _Predicate);
#endif
// for_each
// generate
// generate_n
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
includes(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _BIter>
void
inplace_merge(_BIter, _BIter, _BIter);
template<typename _BIter, typename _Compare>
void
inplace_merge(_BIter, _BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
is_heap(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
_RAIter
is_heap_until(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
is_partitioned(_IIter, _IIter, _Predicate);
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
bool
is_permutation(_FIter1, _FIter1, _FIter2);
template<typename _FIter1, typename _FIter2,
typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
bool
is_permutation(_FIter1, _FIter1, _FIter2, _BinaryPredicate);
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
is_sorted(_FIter, _FIter, _Compare);
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
_FIter
is_sorted_until(_FIter, _FIter, _Compare);
#endif
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
void
iter_swap(_FIter1, _FIter2);
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
_FIter
lower_bound(_FIter, _FIter, const _Tp&, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
make_heap(_RAIter, _RAIter, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
const _Tp&
max(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
const _Tp&
max(const _Tp&, const _Tp&, _Compare);
// max_element
// merge
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
const _Tp&
min(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
const _Tp&
min(const _Tp&, const _Tp&, _Compare);
// min_element
#if __cplusplus >= 201103L
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
pair<const _Tp&, const _Tp&>
minmax(const _Tp&, const _Tp&);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
pair<const _Tp&, const _Tp&>
minmax(const _Tp&, const _Tp&, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
pair<_FIter, _FIter>
minmax_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
pair<_FIter, _FIter>
minmax_element(_FIter, _FIter, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
_Tp
min(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
_Tp
min(initializer_list<_Tp>, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
_Tp
max(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
_Tp
max(initializer_list<_Tp>, _Compare);
template<typename _Tp>
_GLIBCXX14_CONSTEXPR
pair<_Tp, _Tp>
minmax(initializer_list<_Tp>);
template<typename _Tp, typename _Compare>
_GLIBCXX14_CONSTEXPR
pair<_Tp, _Tp>
minmax(initializer_list<_Tp>, _Compare);
#endif
// mismatch
template<typename _BIter>
_GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
next_permutation(_BIter, _BIter, _Compare);
#if __cplusplus >= 201103L
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
bool
none_of(_IIter, _IIter, _Predicate);
#endif
// nth_element
// partial_sort
template<typename _IIter, typename _RAIter>
_GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter);
template<typename _IIter, typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
_RAIter
partial_sort_copy(_IIter, _IIter, _RAIter, _RAIter, _Compare);
// partition
#if __cplusplus >= 201103L
template<typename _IIter, typename _OIter1,
typename _OIter2, typename _Predicate>
_GLIBCXX20_CONSTEXPR
pair<_OIter1, _OIter2>
partition_copy(_IIter, _IIter, _OIter1, _OIter2, _Predicate);
template<typename _FIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_FIter
partition_point(_FIter, _FIter, _Predicate);
#endif
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
pop_heap(_RAIter, _RAIter, _Compare);
template<typename _BIter>
_GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter);
template<typename _BIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
prev_permutation(_BIter, _BIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
push_heap(_RAIter, _RAIter, _Compare);
// random_shuffle
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
remove(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_FIter
remove_if(_FIter, _FIter, _Predicate);
template<typename _IIter, typename _OIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
remove_copy(_IIter, _IIter, _OIter, const _Tp&);
template<typename _IIter, typename _OIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_OIter
remove_copy_if(_IIter, _IIter, _OIter, _Predicate);
// replace
template<typename _IIter, typename _OIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
replace_copy(_IIter, _IIter, _OIter, const _Tp&, const _Tp&);
template<typename _Iter, typename _OIter, typename _Predicate, typename _Tp>
_GLIBCXX20_CONSTEXPR
_OIter
replace_copy_if(_Iter, _Iter, _OIter, _Predicate, const _Tp&);
// replace_if
template<typename _BIter>
_GLIBCXX20_CONSTEXPR
void
reverse(_BIter, _BIter);
template<typename _BIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
reverse_copy(_BIter, _BIter, _OIter);
inline namespace _V2
{
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
rotate(_FIter, _FIter, _FIter);
}
template<typename _FIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
rotate_copy(_FIter, _FIter, _FIter, _OIter);
// search
// search_n
// set_difference
// set_intersection
// set_symmetric_difference
// set_union
#if (__cplusplus >= 201103L) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
template<typename _RAIter, typename _UGenerator>
void
shuffle(_RAIter, _RAIter, _UGenerator&&);
#endif
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
sort_heap(_RAIter, _RAIter, _Compare);
template<typename _BIter, typename _Predicate>
_BIter
stable_partition(_BIter, _BIter, _Predicate);
#if __cplusplus < 201103L
// For C++11 swap() is declared in <type_traits>.
template<typename _Tp, size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline void
swap(_Tp& __a, _Tp& __b);
template<typename _Tp, size_t _Nm>
_GLIBCXX20_CONSTEXPR
inline void
swap(_Tp (&__a)[_Nm], _Tp (&__b)[_Nm]);
#endif
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter2
swap_ranges(_FIter1, _FIter1, _FIter2);
// transform
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter
unique(_FIter, _FIter, _BinaryPredicate);
// unique_copy
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&);
template<typename _FIter, typename _Tp, typename _Compare>
_GLIBCXX20_CONSTEXPR
_FIter
upper_bound(_FIter, _FIter, const _Tp&, _Compare);
_GLIBCXX_BEGIN_NAMESPACE_ALGO
template<typename _FIter>
_GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter);
template<typename _FIter, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter
adjacent_find(_FIter, _FIter, _BinaryPredicate);
template<typename _IIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count(_IIter, _IIter, const _Tp&);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
typename iterator_traits<_IIter>::difference_type
count_if(_IIter, _IIter, _Predicate);
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
bool
equal(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _IIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
_IIter
find(_IIter, _IIter, const _Tp&);
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter1
find_first_of(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _IIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_IIter
find_if(_IIter, _IIter, _Predicate);
template<typename _IIter, typename _Funct>
_GLIBCXX20_CONSTEXPR
_Funct
for_each(_IIter, _IIter, _Funct);
template<typename _FIter, typename _Generator>
_GLIBCXX20_CONSTEXPR
void
generate(_FIter, _FIter, _Generator);
template<typename _OIter, typename _Size, typename _Generator>
_GLIBCXX20_CONSTEXPR
_OIter
generate_n(_OIter, _Size, _Generator);
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2);
template<typename _IIter1, typename _IIter2, typename _Compare>
_GLIBCXX20_CONSTEXPR
bool
lexicographical_compare(_IIter1, _IIter1, _IIter2, _IIter2, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
_FIter
max_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
_FIter
max_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
merge(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _FIter>
_GLIBCXX14_CONSTEXPR
_FIter
min_element(_FIter, _FIter);
template<typename _FIter, typename _Compare>
_GLIBCXX14_CONSTEXPR
_FIter
min_element(_FIter, _FIter, _Compare);
template<typename _IIter1, typename _IIter2>
_GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2);
template<typename _IIter1, typename _IIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
pair<_IIter1, _IIter2>
mismatch(_IIter1, _IIter1, _IIter2, _BinaryPredicate);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
nth_element(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
partial_sort(_RAIter, _RAIter, _RAIter, _Compare);
template<typename _BIter, typename _Predicate>
_GLIBCXX20_CONSTEXPR
_BIter
partition(_BIter, _BIter, _Predicate);
template<typename _RAIter>
void
random_shuffle(_RAIter, _RAIter);
template<typename _RAIter, typename _Generator>
void
random_shuffle(_RAIter, _RAIter,
#if __cplusplus >= 201103L
_Generator&&);
#else
_Generator&);
#endif
template<typename _FIter, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
replace(_FIter, _FIter, const _Tp&, const _Tp&);
template<typename _FIter, typename _Predicate, typename _Tp>
_GLIBCXX20_CONSTEXPR
void
replace_if(_FIter, _FIter, _Predicate, const _Tp&);
template<typename _FIter1, typename _FIter2>
_GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2);
template<typename _FIter1, typename _FIter2, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter1
search(_FIter1, _FIter1, _FIter2, _FIter2, _BinaryPredicate);
template<typename _FIter, typename _Size, typename _Tp>
_GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&);
template<typename _FIter, typename _Size, typename _Tp,
typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_FIter
search_n(_FIter, _FIter, _Size, const _Tp&, _BinaryPredicate);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_intersection(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_symmetric_difference(_IIter1, _IIter1, _IIter2, _IIter2,
_OIter, _Compare);
template<typename _IIter1, typename _IIter2, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _Compare>
_GLIBCXX20_CONSTEXPR
_OIter
set_union(_IIter1, _IIter1, _IIter2, _IIter2, _OIter, _Compare);
template<typename _RAIter>
_GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
_GLIBCXX20_CONSTEXPR
void
sort(_RAIter, _RAIter, _Compare);
template<typename _RAIter>
void
stable_sort(_RAIter, _RAIter);
template<typename _RAIter, typename _Compare>
void
stable_sort(_RAIter, _RAIter, _Compare);
template<typename _IIter, typename _OIter, typename _UnaryOperation>
_GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter, _IIter, _OIter, _UnaryOperation);
template<typename _IIter1, typename _IIter2, typename _OIter,
typename _BinaryOperation>
_GLIBCXX20_CONSTEXPR
_OIter
transform(_IIter1, _IIter1, _IIter2, _OIter, _BinaryOperation);
template<typename _IIter, typename _OIter>
_GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter);
template<typename _IIter, typename _OIter, typename _BinaryPredicate>
_GLIBCXX20_CONSTEXPR
_OIter
unique_copy(_IIter, _IIter, _OIter, _BinaryPredicate);
_GLIBCXX_END_NAMESPACE_ALGO
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#ifdef _GLIBCXX_PARALLEL
# include <parallel/algorithmfwd.h>
#endif
#endif

View File

@ -0,0 +1,743 @@
// Allocator traits -*- C++ -*-
// Copyright (C) 2011-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/alloc_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _ALLOC_TRAITS_H
#define _ALLOC_TRAITS_H 1
#include <bits/stl_construct.h>
#include <bits/memoryfwd.h>
#if __cplusplus >= 201103L
# include <bits/allocator.h>
# include <bits/ptr_traits.h>
# include <ext/numeric_traits.h>
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201103L
#define __cpp_lib_allocator_traits_is_always_equal 201411
struct __allocator_traits_base
{
template<typename _Tp, typename _Up, typename = void>
struct __rebind : __replace_first_arg<_Tp, _Up> { };
template<typename _Tp, typename _Up>
struct __rebind<_Tp, _Up,
__void_t<typename _Tp::template rebind<_Up>::other>>
{ using type = typename _Tp::template rebind<_Up>::other; };
protected:
template<typename _Tp>
using __pointer = typename _Tp::pointer;
template<typename _Tp>
using __c_pointer = typename _Tp::const_pointer;
template<typename _Tp>
using __v_pointer = typename _Tp::void_pointer;
template<typename _Tp>
using __cv_pointer = typename _Tp::const_void_pointer;
template<typename _Tp>
using __pocca = typename _Tp::propagate_on_container_copy_assignment;
template<typename _Tp>
using __pocma = typename _Tp::propagate_on_container_move_assignment;
template<typename _Tp>
using __pocs = typename _Tp::propagate_on_container_swap;
template<typename _Tp>
using __equal = typename _Tp::is_always_equal;
};
template<typename _Alloc, typename _Up>
using __alloc_rebind
= typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
/**
* @brief Uniform interface to all allocator types.
* @ingroup allocators
*/
template<typename _Alloc>
struct allocator_traits : __allocator_traits_base
{
/// The allocator type
typedef _Alloc allocator_type;
/// The allocated type
typedef typename _Alloc::value_type value_type;
/**
* @brief The allocator's pointer type.
*
* @c Alloc::pointer if that type exists, otherwise @c value_type*
*/
using pointer = __detected_or_t<value_type*, __pointer, _Alloc>;
private:
// Select _Func<_Alloc> or pointer_traits<pointer>::rebind<_Tp>
template<template<typename> class _Func, typename _Tp, typename = void>
struct _Ptr
{
using type = typename pointer_traits<pointer>::template rebind<_Tp>;
};
template<template<typename> class _Func, typename _Tp>
struct _Ptr<_Func, _Tp, __void_t<_Func<_Alloc>>>
{
using type = _Func<_Alloc>;
};
// Select _A2::difference_type or pointer_traits<_Ptr>::difference_type
template<typename _A2, typename _PtrT, typename = void>
struct _Diff
{ using type = typename pointer_traits<_PtrT>::difference_type; };
template<typename _A2, typename _PtrT>
struct _Diff<_A2, _PtrT, __void_t<typename _A2::difference_type>>
{ using type = typename _A2::difference_type; };
// Select _A2::size_type or make_unsigned<_DiffT>::type
template<typename _A2, typename _DiffT, typename = void>
struct _Size : make_unsigned<_DiffT> { };
template<typename _A2, typename _DiffT>
struct _Size<_A2, _DiffT, __void_t<typename _A2::size_type>>
{ using type = typename _A2::size_type; };
public:
/**
* @brief The allocator's const pointer type.
*
* @c Alloc::const_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const value_type> </tt>
*/
using const_pointer = typename _Ptr<__c_pointer, const value_type>::type;
/**
* @brief The allocator's void pointer type.
*
* @c Alloc::void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<void> </tt>
*/
using void_pointer = typename _Ptr<__v_pointer, void>::type;
/**
* @brief The allocator's const void pointer type.
*
* @c Alloc::const_void_pointer if that type exists, otherwise
* <tt> pointer_traits<pointer>::rebind<const void> </tt>
*/
using const_void_pointer = typename _Ptr<__cv_pointer, const void>::type;
/**
* @brief The allocator's difference type
*
* @c Alloc::difference_type if that type exists, otherwise
* <tt> pointer_traits<pointer>::difference_type </tt>
*/
using difference_type = typename _Diff<_Alloc, pointer>::type;
/**
* @brief The allocator's size type
*
* @c Alloc::size_type if that type exists, otherwise
* <tt> make_unsigned<difference_type>::type </tt>
*/
using size_type = typename _Size<_Alloc, difference_type>::type;
/**
* @brief How the allocator is propagated on copy assignment
*
* @c Alloc::propagate_on_container_copy_assignment if that type exists,
* otherwise @c false_type
*/
using propagate_on_container_copy_assignment
= __detected_or_t<false_type, __pocca, _Alloc>;
/**
* @brief How the allocator is propagated on move assignment
*
* @c Alloc::propagate_on_container_move_assignment if that type exists,
* otherwise @c false_type
*/
using propagate_on_container_move_assignment
= __detected_or_t<false_type, __pocma, _Alloc>;
/**
* @brief How the allocator is propagated on swap
*
* @c Alloc::propagate_on_container_swap if that type exists,
* otherwise @c false_type
*/
using propagate_on_container_swap
= __detected_or_t<false_type, __pocs, _Alloc>;
/**
* @brief Whether all instances of the allocator type compare equal.
*
* @c Alloc::is_always_equal if that type exists,
* otherwise @c is_empty<Alloc>::type
*/
using is_always_equal
= __detected_or_t<typename is_empty<_Alloc>::type, __equal, _Alloc>;
template<typename _Tp>
using rebind_alloc = __alloc_rebind<_Alloc, _Tp>;
template<typename _Tp>
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
private:
template<typename _Alloc2>
static constexpr auto
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer __hint, int)
-> decltype(__a.allocate(__n, __hint))
{ return __a.allocate(__n, __hint); }
template<typename _Alloc2>
static constexpr pointer
_S_allocate(_Alloc2& __a, size_type __n, const_void_pointer, ...)
{ return __a.allocate(__n); }
template<typename _Tp, typename... _Args>
struct __construct_helper
{
template<typename _Alloc2,
typename = decltype(std::declval<_Alloc2*>()->construct(
std::declval<_Tp*>(), std::declval<_Args>()...))>
static true_type __test(int);
template<typename>
static false_type __test(...);
using type = decltype(__test<_Alloc>(0));
};
template<typename _Tp, typename... _Args>
using __has_construct
= typename __construct_helper<_Tp, _Args...>::type;
template<typename _Tp, typename... _Args>
static _GLIBCXX14_CONSTEXPR _Require<__has_construct<_Tp, _Args...>>
_S_construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
noexcept(noexcept(__a.construct(__p, std::forward<_Args>(__args)...)))
{ __a.construct(__p, std::forward<_Args>(__args)...); }
template<typename _Tp, typename... _Args>
static _GLIBCXX14_CONSTEXPR
_Require<__and_<__not_<__has_construct<_Tp, _Args...>>,
is_constructible<_Tp, _Args...>>>
_S_construct(_Alloc&, _Tp* __p, _Args&&... __args)
noexcept(std::is_nothrow_constructible<_Tp, _Args...>::value)
{
#if __cplusplus <= 201703L
::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
#else
std::construct_at(__p, std::forward<_Args>(__args)...);
#endif
}
template<typename _Alloc2, typename _Tp>
static _GLIBCXX14_CONSTEXPR auto
_S_destroy(_Alloc2& __a, _Tp* __p, int)
noexcept(noexcept(__a.destroy(__p)))
-> decltype(__a.destroy(__p))
{ __a.destroy(__p); }
template<typename _Alloc2, typename _Tp>
static _GLIBCXX14_CONSTEXPR void
_S_destroy(_Alloc2&, _Tp* __p, ...)
noexcept(std::is_nothrow_destructible<_Tp>::value)
{ std::_Destroy(__p); }
template<typename _Alloc2>
static constexpr auto
_S_max_size(_Alloc2& __a, int)
-> decltype(__a.max_size())
{ return __a.max_size(); }
template<typename _Alloc2>
static constexpr size_type
_S_max_size(_Alloc2&, ...)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2466. allocator_traits::max_size() default behavior is incorrect
return __gnu_cxx::__numeric_traits<size_type>::__max
/ sizeof(value_type);
}
template<typename _Alloc2>
static constexpr auto
_S_select(_Alloc2& __a, int)
-> decltype(__a.select_on_container_copy_construction())
{ return __a.select_on_container_copy_construction(); }
template<typename _Alloc2>
static constexpr _Alloc2
_S_select(_Alloc2& __a, ...)
{ return __a; }
public:
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
*
* Calls @c a.allocate(n)
*/
_GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
allocate(_Alloc& __a, size_type __n)
{ return __a.allocate(__n); }
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
* @param __hint Aid to locality.
* @return Memory of suitable size and alignment for @a n objects
* of type @c value_type
*
* Returns <tt> a.allocate(n, hint) </tt> if that expression is
* well-formed, otherwise returns @c a.allocate(n)
*/
_GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
allocate(_Alloc& __a, size_type __n, const_void_pointer __hint)
{ return _S_allocate(__a, __n, __hint, 0); }
/**
* @brief Deallocate memory.
* @param __a An allocator.
* @param __p Pointer to the memory to deallocate.
* @param __n The number of objects space was allocated for.
*
* Calls <tt> a.deallocate(p, n) </tt>
*/
static _GLIBCXX20_CONSTEXPR void
deallocate(_Alloc& __a, pointer __p, size_type __n)
{ __a.deallocate(__p, __n); }
/**
* @brief Construct an object of type `_Tp`
* @param __a An allocator.
* @param __p Pointer to memory of suitable size and alignment for Tp
* @param __args Constructor arguments.
*
* Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
* if that expression is well-formed, otherwise uses placement-new
* to construct an object of type @a _Tp at location @a __p from the
* arguments @a __args...
*/
template<typename _Tp, typename... _Args>
static _GLIBCXX20_CONSTEXPR auto
construct(_Alloc& __a, _Tp* __p, _Args&&... __args)
noexcept(noexcept(_S_construct(__a, __p,
std::forward<_Args>(__args)...)))
-> decltype(_S_construct(__a, __p, std::forward<_Args>(__args)...))
{ _S_construct(__a, __p, std::forward<_Args>(__args)...); }
/**
* @brief Destroy an object of type @a _Tp
* @param __a An allocator.
* @param __p Pointer to the object to destroy
*
* Calls @c __a.destroy(__p) if that expression is well-formed,
* otherwise calls @c __p->~_Tp()
*/
template<typename _Tp>
static _GLIBCXX20_CONSTEXPR void
destroy(_Alloc& __a, _Tp* __p)
noexcept(noexcept(_S_destroy(__a, __p, 0)))
{ _S_destroy(__a, __p, 0); }
/**
* @brief The maximum supported allocation size
* @param __a An allocator.
* @return @c __a.max_size() or @c numeric_limits<size_type>::max()
*
* Returns @c __a.max_size() if that expression is well-formed,
* otherwise returns @c numeric_limits<size_type>::max()
*/
static _GLIBCXX20_CONSTEXPR size_type
max_size(const _Alloc& __a) noexcept
{ return _S_max_size(__a, 0); }
/**
* @brief Obtain an allocator to use when copying a container.
* @param __rhs An allocator.
* @return @c __rhs.select_on_container_copy_construction() or @a __rhs
*
* Returns @c __rhs.select_on_container_copy_construction() if that
* expression is well-formed, otherwise returns @a __rhs
*/
static _GLIBCXX20_CONSTEXPR _Alloc
select_on_container_copy_construction(const _Alloc& __rhs)
{ return _S_select(__rhs, 0); }
};
#if __cplusplus > 201703L
# define __cpp_lib_constexpr_dynamic_alloc 201907L
#endif
/// Partial specialization for std::allocator.
template<typename _Tp>
struct allocator_traits<allocator<_Tp>>
{
/// The allocator type
using allocator_type = allocator<_Tp>;
/// The allocated type
using value_type = _Tp;
/// The allocator's pointer type.
using pointer = _Tp*;
/// The allocator's const pointer type.
using const_pointer = const _Tp*;
/// The allocator's void pointer type.
using void_pointer = void*;
/// The allocator's const void pointer type.
using const_void_pointer = const void*;
/// The allocator's difference type
using difference_type = std::ptrdiff_t;
/// The allocator's size type
using size_type = std::size_t;
/// How the allocator is propagated on copy assignment
using propagate_on_container_copy_assignment = false_type;
/// How the allocator is propagated on move assignment
using propagate_on_container_move_assignment = true_type;
/// How the allocator is propagated on swap
using propagate_on_container_swap = false_type;
/// Whether all instances of the allocator type compare equal.
using is_always_equal = true_type;
template<typename _Up>
using rebind_alloc = allocator<_Up>;
template<typename _Up>
using rebind_traits = allocator_traits<allocator<_Up>>;
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
*
* Calls @c a.allocate(n)
*/
_GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
allocate(allocator_type& __a, size_type __n)
{ return __a.allocate(__n); }
/**
* @brief Allocate memory.
* @param __a An allocator.
* @param __n The number of objects to allocate space for.
* @param __hint Aid to locality.
* @return Memory of suitable size and alignment for @a n objects
* of type @c value_type
*
* Returns <tt> a.allocate(n, hint) </tt>
*/
_GLIBCXX_NODISCARD static _GLIBCXX20_CONSTEXPR pointer
allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
{
#if __cplusplus <= 201703L
return __a.allocate(__n, __hint);
#else
return __a.allocate(__n);
#endif
}
/**
* @brief Deallocate memory.
* @param __a An allocator.
* @param __p Pointer to the memory to deallocate.
* @param __n The number of objects space was allocated for.
*
* Calls <tt> a.deallocate(p, n) </tt>
*/
static _GLIBCXX20_CONSTEXPR void
deallocate(allocator_type& __a, pointer __p, size_type __n)
{ __a.deallocate(__p, __n); }
/**
* @brief Construct an object of type `_Up`
* @param __a An allocator.
* @param __p Pointer to memory of suitable size and alignment for
* an object of type `_Up`.
* @param __args Constructor arguments.
*
* Calls `__a.construct(__p, std::forward<_Args>(__args)...)`
* in C++11, C++14 and C++17. Changed in C++20 to call
* `std::construct_at(__p, std::forward<_Args>(__args)...)` instead.
*/
template<typename _Up, typename... _Args>
static _GLIBCXX20_CONSTEXPR void
construct(allocator_type& __a __attribute__((__unused__)), _Up* __p,
_Args&&... __args)
noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
{
#if __cplusplus <= 201703L
__a.construct(__p, std::forward<_Args>(__args)...);
#else
std::construct_at(__p, std::forward<_Args>(__args)...);
#endif
}
/**
* @brief Destroy an object of type @a _Up
* @param __a An allocator.
* @param __p Pointer to the object to destroy
*
* Calls @c __a.destroy(__p).
*/
template<typename _Up>
static _GLIBCXX20_CONSTEXPR void
destroy(allocator_type& __a __attribute__((__unused__)), _Up* __p)
noexcept(is_nothrow_destructible<_Up>::value)
{
#if __cplusplus <= 201703L
__a.destroy(__p);
#else
std::destroy_at(__p);
#endif
}
/**
* @brief The maximum supported allocation size
* @param __a An allocator.
* @return @c __a.max_size()
*/
static _GLIBCXX20_CONSTEXPR size_type
max_size(const allocator_type& __a __attribute__((__unused__))) noexcept
{
#if __cplusplus <= 201703L
return __a.max_size();
#else
return size_t(-1) / sizeof(value_type);
#endif
}
/**
* @brief Obtain an allocator to use when copying a container.
* @param __rhs An allocator.
* @return @c __rhs
*/
static _GLIBCXX20_CONSTEXPR allocator_type
select_on_container_copy_construction(const allocator_type& __rhs)
{ return __rhs; }
};
#if __cplusplus < 201703L
template<typename _Alloc>
inline void
__do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
{ __one = __two; }
template<typename _Alloc>
inline void
__do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
{ }
#endif
template<typename _Alloc>
_GLIBCXX14_CONSTEXPR inline void
__alloc_on_copy(_Alloc& __one, const _Alloc& __two)
{
typedef allocator_traits<_Alloc> __traits;
typedef typename __traits::propagate_on_container_copy_assignment __pocca;
#if __cplusplus >= 201703L
if constexpr (__pocca::value)
__one = __two;
#else
__do_alloc_on_copy(__one, __two, __pocca());
#endif
}
template<typename _Alloc>
constexpr _Alloc
__alloc_on_copy(const _Alloc& __a)
{
typedef allocator_traits<_Alloc> __traits;
return __traits::select_on_container_copy_construction(__a);
}
#if __cplusplus < 201703L
template<typename _Alloc>
inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
{ __one = std::move(__two); }
template<typename _Alloc>
inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
{ }
#endif
template<typename _Alloc>
_GLIBCXX14_CONSTEXPR inline void
__alloc_on_move(_Alloc& __one, _Alloc& __two)
{
typedef allocator_traits<_Alloc> __traits;
typedef typename __traits::propagate_on_container_move_assignment __pocma;
#if __cplusplus >= 201703L
if constexpr (__pocma::value)
__one = std::move(__two);
#else
__do_alloc_on_move(__one, __two, __pocma());
#endif
}
#if __cplusplus < 201703L
template<typename _Alloc>
inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
{
using std::swap;
swap(__one, __two);
}
template<typename _Alloc>
inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
{ }
#endif
template<typename _Alloc>
_GLIBCXX14_CONSTEXPR inline void
__alloc_on_swap(_Alloc& __one, _Alloc& __two)
{
typedef allocator_traits<_Alloc> __traits;
typedef typename __traits::propagate_on_container_swap __pocs;
#if __cplusplus >= 201703L
if constexpr (__pocs::value)
{
using std::swap;
swap(__one, __two);
}
#else
__do_alloc_on_swap(__one, __two, __pocs());
#endif
}
template<typename _Alloc, typename _Tp,
typename _ValueT = __remove_cvref_t<typename _Alloc::value_type>,
typename = void>
struct __is_alloc_insertable_impl
: false_type
{ };
template<typename _Alloc, typename _Tp, typename _ValueT>
struct __is_alloc_insertable_impl<_Alloc, _Tp, _ValueT,
__void_t<decltype(allocator_traits<_Alloc>::construct(
std::declval<_Alloc&>(), std::declval<_ValueT*>(),
std::declval<_Tp>()))>>
: true_type
{ };
// true if _Alloc::value_type is CopyInsertable into containers using _Alloc
// (might be wrong if _Alloc::construct exists but is not constrained,
// i.e. actually trying to use it would still be invalid. Use with caution.)
template<typename _Alloc>
struct __is_copy_insertable
: __is_alloc_insertable_impl<_Alloc,
typename _Alloc::value_type const&>::type
{ };
// std::allocator<_Tp> just requires CopyConstructible
template<typename _Tp>
struct __is_copy_insertable<allocator<_Tp>>
: is_copy_constructible<_Tp>
{ };
// true if _Alloc::value_type is MoveInsertable into containers using _Alloc
// (might be wrong if _Alloc::construct exists but is not constrained,
// i.e. actually trying to use it would still be invalid. Use with caution.)
template<typename _Alloc>
struct __is_move_insertable
: __is_alloc_insertable_impl<_Alloc, typename _Alloc::value_type>::type
{ };
// std::allocator<_Tp> just requires MoveConstructible
template<typename _Tp>
struct __is_move_insertable<allocator<_Tp>>
: is_move_constructible<_Tp>
{ };
// Trait to detect Allocator-like types.
template<typename _Alloc, typename = void>
struct __is_allocator : false_type { };
template<typename _Alloc>
struct __is_allocator<_Alloc,
__void_t<typename _Alloc::value_type,
decltype(std::declval<_Alloc&>().allocate(size_t{}))>>
: true_type { };
template<typename _Alloc>
using _RequireAllocator
= typename enable_if<__is_allocator<_Alloc>::value, _Alloc>::type;
template<typename _Alloc>
using _RequireNotAllocator
= typename enable_if<!__is_allocator<_Alloc>::value, _Alloc>::type;
#endif // C++11
/**
* Destroy a range of objects using the supplied allocator. For
* non-default allocators we do not optimize away invocation of
* destroy() even if _Tp has a trivial destructor.
*/
template<typename _ForwardIterator, typename _Allocator>
void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
_Allocator& __alloc)
{
for (; __first != __last; ++__first)
#if __cplusplus < 201103L
__alloc.destroy(std::__addressof(*__first));
#else
allocator_traits<_Allocator>::destroy(__alloc,
std::__addressof(*__first));
#endif
}
template<typename _ForwardIterator, typename _Tp>
inline void
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
allocator<_Tp>&)
{
_Destroy(__first, __last);
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // _ALLOC_TRAITS_H

View File

@ -0,0 +1,104 @@
// Guarded Allocation -*- C++ -*-
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/allocated_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _ALLOCATED_PTR_H
#define _ALLOCATED_PTR_H 1
#if __cplusplus < 201103L
# include <bits/c++0xwarning.h>
#else
# include <type_traits>
# include <bits/ptr_traits.h>
# include <bits/alloc_traits.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Non-standard RAII type for managing pointers obtained from allocators.
template<typename _Alloc>
struct __allocated_ptr
{
using pointer = typename allocator_traits<_Alloc>::pointer;
using value_type = typename allocator_traits<_Alloc>::value_type;
/// Take ownership of __ptr
__allocated_ptr(_Alloc& __a, pointer __ptr) noexcept
: _M_alloc(std::__addressof(__a)), _M_ptr(__ptr)
{ }
/// Convert __ptr to allocator's pointer type and take ownership of it
template<typename _Ptr,
typename _Req = _Require<is_same<_Ptr, value_type*>>>
__allocated_ptr(_Alloc& __a, _Ptr __ptr)
: _M_alloc(std::__addressof(__a)),
_M_ptr(pointer_traits<pointer>::pointer_to(*__ptr))
{ }
/// Transfer ownership of the owned pointer
__allocated_ptr(__allocated_ptr&& __gd) noexcept
: _M_alloc(__gd._M_alloc), _M_ptr(__gd._M_ptr)
{ __gd._M_ptr = nullptr; }
/// Deallocate the owned pointer
~__allocated_ptr()
{
if (_M_ptr != nullptr)
std::allocator_traits<_Alloc>::deallocate(*_M_alloc, _M_ptr, 1);
}
/// Release ownership of the owned pointer
__allocated_ptr&
operator=(std::nullptr_t) noexcept
{
_M_ptr = nullptr;
return *this;
}
/// Get the address that the owned pointer refers to.
value_type* get() { return std::__to_address(_M_ptr); }
private:
_Alloc* _M_alloc;
pointer _M_ptr;
};
/// Allocate space for a single object using __a
template<typename _Alloc>
__allocated_ptr<_Alloc>
__allocate_guarded(_Alloc& __a)
{
return { __a, std::allocator_traits<_Alloc>::allocate(__a, 1) };
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif
#endif

View File

@ -0,0 +1,343 @@
// Allocators -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
* Copyright (c) 1996-1997
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** @file bits/allocator.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{memory}
*/
#ifndef _ALLOCATOR_H
#define _ALLOCATOR_H 1
#include <bits/c++allocator.h> // Define the base class to std::allocator.
#include <bits/memoryfwd.h>
#if __cplusplus >= 201103L
#include <type_traits>
#endif
#define __cpp_lib_incomplete_container_elements 201505
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup allocators
* @{
*/
// Since C++20 the primary template should be used for allocator<void>,
// but then it would have a non-trivial default ctor and dtor, which
// would be an ABI change. So C++20 still uses the allocator<void> explicit
// specialization, with the historical ABI properties, but with the same
// members that are present in the primary template.
#if ! _GLIBCXX_INLINE_VERSION
/// allocator<void> specialization.
template<>
class allocator<void>
{
public:
typedef void value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if __cplusplus <= 201703L
// These were removed for C++20.
typedef void* pointer;
typedef const void* const_pointer;
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
#endif
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
#if __cplusplus > 201703L
allocator() = default;
template<typename _Up>
constexpr
allocator(const allocator<_Up>&) noexcept { }
// No allocate member because it's ill-formed by LWG 3307.
// No deallocate member because it would be undefined to call it
// with any pointer which wasn't obtained from allocate.
#else // ! C++20
// allocator_traits<allocator<void>> uses construct and destroy.
template<typename _Up, typename... _Args>
void
construct(_Up* __p, _Args&&... __args)
noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
template<typename _Up>
void
destroy(_Up* __p)
noexcept(std::is_nothrow_destructible<_Up>::value)
{ __p->~_Up(); }
#endif // C++17
#endif // C++11
};
#endif // ! _GLIBCXX_INLINE_VERSION
/**
* @brief The @a standard allocator, as per C++03 [20.4.1].
*
* See https://gcc.gnu.org/onlinedocs/libstdc++/manual/memory.html#std.util.memory.allocator
* for further details.
*
* @tparam _Tp Type of allocated object.
*/
template<typename _Tp>
class allocator : public __allocator_base<_Tp>
{
public:
typedef _Tp value_type;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
#if __cplusplus <= 201703L
// These were removed for C++20.
typedef _Tp* pointer;
typedef const _Tp* const_pointer;
typedef _Tp& reference;
typedef const _Tp& const_reference;
template<typename _Tp1>
struct rebind
{ typedef allocator<_Tp1> other; };
#endif
#if __cplusplus >= 201103L
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2103. std::allocator propagate_on_container_move_assignment
typedef true_type propagate_on_container_move_assignment;
typedef true_type is_always_equal;
#endif
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3035. std::allocator's constructors should be constexpr
_GLIBCXX20_CONSTEXPR
allocator() _GLIBCXX_NOTHROW { }
_GLIBCXX20_CONSTEXPR
allocator(const allocator& __a) _GLIBCXX_NOTHROW
: __allocator_base<_Tp>(__a) { }
#if __cplusplus >= 201103L
// Avoid implicit deprecation.
allocator& operator=(const allocator&) = default;
#endif
template<typename _Tp1>
_GLIBCXX20_CONSTEXPR
allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
#if __cpp_constexpr_dynamic_alloc
constexpr
#endif
~allocator() _GLIBCXX_NOTHROW { }
#if __cplusplus > 201703L
[[nodiscard,__gnu__::__always_inline__]]
constexpr _Tp*
allocate(size_t __n)
{
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return static_cast<_Tp*>(::operator new(__n * sizeof(_Tp)));
#endif
return __allocator_base<_Tp>::allocate(__n, 0);
}
[[__gnu__::__always_inline__]]
constexpr void
deallocate(_Tp* __p, size_t __n)
{
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
{
::operator delete(__p);
return;
}
#endif
__allocator_base<_Tp>::deallocate(__p, __n);
}
#endif // C++20
friend _GLIBCXX20_CONSTEXPR bool
operator==(const allocator&, const allocator&) _GLIBCXX_NOTHROW
{ return true; }
#if __cpp_impl_three_way_comparison < 201907L
friend _GLIBCXX20_CONSTEXPR bool
operator!=(const allocator&, const allocator&) _GLIBCXX_NOTHROW
{ return false; }
#endif
// Inherit everything else.
};
template<typename _T1, typename _T2>
inline _GLIBCXX20_CONSTEXPR bool
operator==(const allocator<_T1>&, const allocator<_T2>&)
_GLIBCXX_NOTHROW
{ return true; }
#if __cpp_impl_three_way_comparison < 201907L
template<typename _T1, typename _T2>
inline _GLIBCXX20_CONSTEXPR bool
operator!=(const allocator<_T1>&, const allocator<_T2>&)
_GLIBCXX_NOTHROW
{ return false; }
#endif
// Invalid allocator<cv T> partial specializations.
// allocator_traits::rebind_alloc can be used to form a valid allocator type.
template<typename _Tp>
class allocator<const _Tp>
{
public:
typedef _Tp value_type;
template<typename _Up> allocator(const allocator<_Up>&) { }
};
template<typename _Tp>
class allocator<volatile _Tp>
{
public:
typedef _Tp value_type;
template<typename _Up> allocator(const allocator<_Up>&) { }
};
template<typename _Tp>
class allocator<const volatile _Tp>
{
public:
typedef _Tp value_type;
template<typename _Up> allocator(const allocator<_Up>&) { }
};
/// @} group allocator
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class allocator<char>;
extern template class allocator<wchar_t>;
#endif
// Undefine.
#undef __allocator_base
// To implement Option 3 of DR 431.
template<typename _Alloc, bool = __is_empty(_Alloc)>
struct __alloc_swap
{ static void _S_do_it(_Alloc&, _Alloc&) _GLIBCXX_NOEXCEPT { } };
template<typename _Alloc>
struct __alloc_swap<_Alloc, false>
{
static void
_S_do_it(_Alloc& __one, _Alloc& __two) _GLIBCXX_NOEXCEPT
{
// Precondition: swappable allocators.
if (__one != __two)
swap(__one, __two);
}
};
// Optimize for stateless allocators.
template<typename _Alloc, bool = __is_empty(_Alloc)>
struct __alloc_neq
{
static bool
_S_do_it(const _Alloc&, const _Alloc&)
{ return false; }
};
template<typename _Alloc>
struct __alloc_neq<_Alloc, false>
{
static bool
_S_do_it(const _Alloc& __one, const _Alloc& __two)
{ return __one != __two; }
};
#if __cplusplus >= 201103L
template<typename _Tp, bool
= __or_<is_copy_constructible<typename _Tp::value_type>,
is_nothrow_move_constructible<typename _Tp::value_type>>::value>
struct __shrink_to_fit_aux
{ static bool _S_do_it(_Tp&) noexcept { return false; } };
template<typename _Tp>
struct __shrink_to_fit_aux<_Tp, true>
{
static bool
_S_do_it(_Tp& __c) noexcept
{
#if __cpp_exceptions
try
{
_Tp(__make_move_if_noexcept_iterator(__c.begin()),
__make_move_if_noexcept_iterator(__c.end()),
__c.get_allocator()).swap(__c);
return true;
}
catch(...)
{ return false; }
#else
return false;
#endif
}
};
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@ -0,0 +1,290 @@
// -*- C++ -*- header.
// Copyright (C) 2015-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/atomic_futex.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
*/
#ifndef _GLIBCXX_ATOMIC_FUTEX_H
#define _GLIBCXX_ATOMIC_FUTEX_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <atomic>
#include <chrono>
#if ! (defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1)
#include <mutex>
#include <condition_variable>
#endif
#ifndef _GLIBCXX_ALWAYS_INLINE
#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifdef _GLIBCXX_HAS_GTHREADS
#if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
struct __atomic_futex_unsigned_base
{
// Returns false iff a timeout occurred.
bool
_M_futex_wait_until(unsigned *__addr, unsigned __val, bool __has_timeout,
chrono::seconds __s, chrono::nanoseconds __ns);
// This can be executed after the object has been destroyed.
static void _M_futex_notify_all(unsigned* __addr);
};
template <unsigned _Waiter_bit = 0x80000000>
class __atomic_futex_unsigned : __atomic_futex_unsigned_base
{
typedef chrono::system_clock __clock_t;
// This must be lock-free and at offset 0.
atomic<unsigned> _M_data;
public:
explicit
__atomic_futex_unsigned(unsigned __data) : _M_data(__data)
{ }
_GLIBCXX_ALWAYS_INLINE unsigned
_M_load(memory_order __mo)
{
return _M_data.load(__mo) & ~_Waiter_bit;
}
private:
// If a timeout occurs, returns a current value after the timeout;
// otherwise, returns the operand's value if equal is true or a different
// value if equal is false.
// The assumed value is the caller's assumption about the current value
// when making the call.
unsigned
_M_load_and_test_until(unsigned __assumed, unsigned __operand,
bool __equal, memory_order __mo, bool __has_timeout,
chrono::seconds __s, chrono::nanoseconds __ns)
{
for (;;)
{
// Don't bother checking the value again because we expect the caller
// to have done it recently.
// memory_order_relaxed is sufficient because we can rely on just the
// modification order (store_notify uses an atomic RMW operation too),
// and the futex syscalls synchronize between themselves.
_M_data.fetch_or(_Waiter_bit, memory_order_relaxed);
bool __ret = _M_futex_wait_until((unsigned*)(void*)&_M_data,
__assumed | _Waiter_bit,
__has_timeout, __s, __ns);
// Fetch the current value after waiting (clears _Waiter_bit).
__assumed = _M_load(__mo);
if (!__ret || ((__operand == __assumed) == __equal))
return __assumed;
// TODO adapt wait time
}
}
// Returns the operand's value if equal is true or a different value if
// equal is false.
// The assumed value is the caller's assumption about the current value
// when making the call.
unsigned
_M_load_and_test(unsigned __assumed, unsigned __operand,
bool __equal, memory_order __mo)
{
return _M_load_and_test_until(__assumed, __operand, __equal, __mo,
false, {}, {});
}
// If a timeout occurs, returns a current value after the timeout;
// otherwise, returns the operand's value if equal is true or a different
// value if equal is false.
// The assumed value is the caller's assumption about the current value
// when making the call.
template<typename _Dur>
unsigned
_M_load_and_test_until_impl(unsigned __assumed, unsigned __operand,
bool __equal, memory_order __mo,
const chrono::time_point<__clock_t, _Dur>& __atime)
{
auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
// XXX correct?
return _M_load_and_test_until(__assumed, __operand, __equal, __mo,
true, __s.time_since_epoch(), __ns);
}
public:
_GLIBCXX_ALWAYS_INLINE unsigned
_M_load_when_not_equal(unsigned __val, memory_order __mo)
{
unsigned __i = _M_load(__mo);
if ((__i & ~_Waiter_bit) != __val)
return (__i & ~_Waiter_bit);
// TODO Spin-wait first.
return _M_load_and_test(__i, __val, false, __mo);
}
_GLIBCXX_ALWAYS_INLINE void
_M_load_when_equal(unsigned __val, memory_order __mo)
{
unsigned __i = _M_load(__mo);
if ((__i & ~_Waiter_bit) == __val)
return;
// TODO Spin-wait first.
_M_load_and_test(__i, __val, true, __mo);
}
// Returns false iff a timeout occurred.
template<typename _Rep, typename _Period>
_GLIBCXX_ALWAYS_INLINE bool
_M_load_when_equal_for(unsigned __val, memory_order __mo,
const chrono::duration<_Rep, _Period>& __rtime)
{
return _M_load_when_equal_until(__val, __mo,
__clock_t::now() + __rtime);
}
// Returns false iff a timeout occurred.
template<typename _Clock, typename _Duration>
_GLIBCXX_ALWAYS_INLINE bool
_M_load_when_equal_until(unsigned __val, memory_order __mo,
const chrono::time_point<_Clock, _Duration>& __atime)
{
// DR 887 - Sync unknown clock to known clock.
const typename _Clock::time_point __c_entry = _Clock::now();
const __clock_t::time_point __s_entry = __clock_t::now();
const auto __delta = __atime - __c_entry;
const auto __s_atime = __s_entry + __delta;
return _M_load_when_equal_until(__val, __mo, __s_atime);
}
// Returns false iff a timeout occurred.
template<typename _Duration>
_GLIBCXX_ALWAYS_INLINE bool
_M_load_when_equal_until(unsigned __val, memory_order __mo,
const chrono::time_point<__clock_t, _Duration>& __atime)
{
unsigned __i = _M_load(__mo);
if ((__i & ~_Waiter_bit) == __val)
return true;
// TODO Spin-wait first. Ignore effect on timeout.
__i = _M_load_and_test_until_impl(__i, __val, true, __mo, __atime);
return (__i & ~_Waiter_bit) == __val;
}
_GLIBCXX_ALWAYS_INLINE void
_M_store_notify_all(unsigned __val, memory_order __mo)
{
unsigned* __futex = (unsigned *)(void *)&_M_data;
if (_M_data.exchange(__val, __mo) & _Waiter_bit)
_M_futex_notify_all(__futex);
}
};
#else // ! (_GLIBCXX_HAVE_LINUX_FUTEX && ATOMIC_INT_LOCK_FREE > 1)
// If futexes are not available, use a mutex and a condvar to wait.
// Because we access the data only within critical sections, all accesses
// are sequentially consistent; thus, we satisfy any provided memory_order.
template <unsigned _Waiter_bit = 0x80000000>
class __atomic_futex_unsigned
{
typedef chrono::system_clock __clock_t;
unsigned _M_data;
mutex _M_mutex;
condition_variable _M_condvar;
public:
explicit
__atomic_futex_unsigned(unsigned __data) : _M_data(__data)
{ }
_GLIBCXX_ALWAYS_INLINE unsigned
_M_load(memory_order __mo)
{
unique_lock<mutex> __lock(_M_mutex);
return _M_data;
}
_GLIBCXX_ALWAYS_INLINE unsigned
_M_load_when_not_equal(unsigned __val, memory_order __mo)
{
unique_lock<mutex> __lock(_M_mutex);
while (_M_data == __val)
_M_condvar.wait(__lock);
return _M_data;
}
_GLIBCXX_ALWAYS_INLINE void
_M_load_when_equal(unsigned __val, memory_order __mo)
{
unique_lock<mutex> __lock(_M_mutex);
while (_M_data != __val)
_M_condvar.wait(__lock);
}
template<typename _Rep, typename _Period>
_GLIBCXX_ALWAYS_INLINE bool
_M_load_when_equal_for(unsigned __val, memory_order __mo,
const chrono::duration<_Rep, _Period>& __rtime)
{
unique_lock<mutex> __lock(_M_mutex);
return _M_condvar.wait_for(__lock, __rtime,
[&] { return _M_data == __val;});
}
template<typename _Clock, typename _Duration>
_GLIBCXX_ALWAYS_INLINE bool
_M_load_when_equal_until(unsigned __val, memory_order __mo,
const chrono::time_point<_Clock, _Duration>& __atime)
{
unique_lock<mutex> __lock(_M_mutex);
return _M_condvar.wait_until(__lock, __atime,
[&] { return _M_data == __val;});
}
_GLIBCXX_ALWAYS_INLINE void
_M_store_notify_all(unsigned __val, memory_order __mo)
{
unique_lock<mutex> __lock(_M_mutex);
_M_data = __val;
_M_condvar.notify_all();
}
};
#endif // _GLIBCXX_HAVE_LINUX_FUTEX && ATOMIC_INT_LOCK_FREE > 1
#endif // _GLIBCXX_HAS_GTHREADS
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@ -0,0 +1,66 @@
// -*- C++ -*- header.
// Copyright (C) 2008-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/atomic_lockfree_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{atomic}
*/
#ifndef _GLIBCXX_ATOMIC_LOCK_FREE_H
#define _GLIBCXX_ATOMIC_LOCK_FREE_H 1
#pragma GCC system_header
/**
* @addtogroup atomics
* @{
*/
/**
* Lock-free property.
*
* 0 indicates that the types are never lock-free.
* 1 indicates that the types are sometimes lock-free.
* 2 indicates that the types are always lock-free.
*/
#if __cplusplus >= 201103L
#define ATOMIC_BOOL_LOCK_FREE __GCC_ATOMIC_BOOL_LOCK_FREE
#define ATOMIC_CHAR_LOCK_FREE __GCC_ATOMIC_CHAR_LOCK_FREE
#define ATOMIC_WCHAR_T_LOCK_FREE __GCC_ATOMIC_WCHAR_T_LOCK_FREE
#ifdef _GLIBCXX_USE_CHAR8_T
#define ATOMIC_CHAR8_T_LOCK_FREE __GCC_ATOMIC_CHAR8_T_LOCK_FREE
#endif
#define ATOMIC_CHAR16_T_LOCK_FREE __GCC_ATOMIC_CHAR16_T_LOCK_FREE
#define ATOMIC_CHAR32_T_LOCK_FREE __GCC_ATOMIC_CHAR32_T_LOCK_FREE
#define ATOMIC_SHORT_LOCK_FREE __GCC_ATOMIC_SHORT_LOCK_FREE
#define ATOMIC_INT_LOCK_FREE __GCC_ATOMIC_INT_LOCK_FREE
#define ATOMIC_LONG_LOCK_FREE __GCC_ATOMIC_LONG_LOCK_FREE
#define ATOMIC_LLONG_LOCK_FREE __GCC_ATOMIC_LLONG_LOCK_FREE
#define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE
#endif
/// @} group atomics
#endif

View File

@ -0,0 +1,518 @@
// Iostreams base classes -*- C++ -*-
// Copyright (C) 1997-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/basic_ios.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
#ifndef _BASIC_IOS_H
#define _BASIC_IOS_H 1
#pragma GCC system_header
#include <bits/localefwd.h>
#include <bits/locale_classes.h>
#include <bits/locale_facets.h>
#include <bits/streambuf_iterator.h>
#include <bits/move.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Facet>
inline const _Facet&
__check_facet(const _Facet* __f)
{
if (!__f)
__throw_bad_cast();
return *__f;
}
/**
* @brief Template class basic_ios, virtual base class for all
* stream classes.
* @ingroup io
*
* @tparam _CharT Type of character stream.
* @tparam _Traits Traits for character type, defaults to
* char_traits<_CharT>.
*
* Most of the member functions called dispatched on stream objects
* (e.g., @c std::cout.foo(bar);) are consolidated in this class.
*/
template<typename _CharT, typename _Traits>
class basic_ios : public ios_base
{
public:
///@{
/**
* These are standard types. They permit a standardized way of
* referring to names of (or names dependent on) the template
* parameters, which are specific to the implementation.
*/
typedef _CharT char_type;
typedef typename _Traits::int_type int_type;
typedef typename _Traits::pos_type pos_type;
typedef typename _Traits::off_type off_type;
typedef _Traits traits_type;
///@}
///@{
/**
* These are non-standard types.
*/
typedef ctype<_CharT> __ctype_type;
typedef num_put<_CharT, ostreambuf_iterator<_CharT, _Traits> >
__num_put_type;
typedef num_get<_CharT, istreambuf_iterator<_CharT, _Traits> >
__num_get_type;
///@}
// Data members:
protected:
basic_ostream<_CharT, _Traits>* _M_tie;
mutable char_type _M_fill;
mutable bool _M_fill_init;
basic_streambuf<_CharT, _Traits>* _M_streambuf;
// Cached use_facet<ctype>, which is based on the current locale info.
const __ctype_type* _M_ctype;
// For ostream.
const __num_put_type* _M_num_put;
// For istream.
const __num_get_type* _M_num_get;
public:
///@{
/**
* @brief The quick-and-easy status check.
*
* This allows you to write constructs such as
* <code>if (!a_stream) ...</code> and <code>while (a_stream) ...</code>
*/
#if __cplusplus >= 201103L
explicit operator bool() const
{ return !this->fail(); }
#else
operator void*() const
{ return this->fail() ? 0 : const_cast<basic_ios*>(this); }
#endif
bool
operator!() const
{ return this->fail(); }
///@}
/**
* @brief Returns the error state of the stream buffer.
* @return A bit pattern (well, isn't everything?)
*
* See std::ios_base::iostate for the possible bit values. Most
* users will call one of the interpreting wrappers, e.g., good().
*/
iostate
rdstate() const
{ return _M_streambuf_state; }
/**
* @brief [Re]sets the error state.
* @param __state The new state flag(s) to set.
*
* See std::ios_base::iostate for the possible bit values. Most
* users will not need to pass an argument.
*/
void
clear(iostate __state = goodbit);
/**
* @brief Sets additional flags in the error state.
* @param __state The additional state flag(s) to set.
*
* See std::ios_base::iostate for the possible bit values.
*/
void
setstate(iostate __state)
{ this->clear(this->rdstate() | __state); }
// Flip the internal state on for the proper state bits, then
// rethrows the propagated exception if bit also set in
// exceptions().
void
_M_setstate(iostate __state)
{
// 27.6.1.2.1 Common requirements.
// Turn this on without causing an ios::failure to be thrown.
_M_streambuf_state |= __state;
if (this->exceptions() & __state)
__throw_exception_again;
}
/**
* @brief Fast error checking.
* @return True if no error flags are set.
*
* A wrapper around rdstate.
*/
bool
good() const
{ return this->rdstate() == 0; }
/**
* @brief Fast error checking.
* @return True if the eofbit is set.
*
* Note that other iostate flags may also be set.
*/
bool
eof() const
{ return (this->rdstate() & eofbit) != 0; }
/**
* @brief Fast error checking.
* @return True if either the badbit or the failbit is set.
*
* Checking the badbit in fail() is historical practice.
* Note that other iostate flags may also be set.
*/
bool
fail() const
{ return (this->rdstate() & (badbit | failbit)) != 0; }
/**
* @brief Fast error checking.
* @return True if the badbit is set.
*
* Note that other iostate flags may also be set.
*/
bool
bad() const
{ return (this->rdstate() & badbit) != 0; }
/**
* @brief Throwing exceptions on errors.
* @return The current exceptions mask.
*
* This changes nothing in the stream. See the one-argument version
* of exceptions(iostate) for the meaning of the return value.
*/
iostate
exceptions() const
{ return _M_exception; }
/**
* @brief Throwing exceptions on errors.
* @param __except The new exceptions mask.
*
* By default, error flags are set silently. You can set an
* exceptions mask for each stream; if a bit in the mask becomes set
* in the error flags, then an exception of type
* std::ios_base::failure is thrown.
*
* If the error flag is already set when the exceptions mask is
* added, the exception is immediately thrown. Try running the
* following under GCC 3.1 or later:
* @code
* #include <iostream>
* #include <fstream>
* #include <exception>
*
* int main()
* {
* std::set_terminate (__gnu_cxx::__verbose_terminate_handler);
*
* std::ifstream f ("/etc/motd");
*
* std::cerr << "Setting badbit\n";
* f.setstate (std::ios_base::badbit);
*
* std::cerr << "Setting exception mask\n";
* f.exceptions (std::ios_base::badbit);
* }
* @endcode
*/
void
exceptions(iostate __except)
{
_M_exception = __except;
this->clear(_M_streambuf_state);
}
// Constructor/destructor:
/**
* @brief Constructor performs initialization.
*
* The parameter is passed by derived streams.
*/
explicit
basic_ios(basic_streambuf<_CharT, _Traits>* __sb)
: ios_base(), _M_tie(0), _M_fill(), _M_fill_init(false), _M_streambuf(0),
_M_ctype(0), _M_num_put(0), _M_num_get(0)
{ this->init(__sb); }
/**
* @brief Empty.
*
* The destructor does nothing. More specifically, it does not
* destroy the streambuf held by rdbuf().
*/
virtual
~basic_ios() { }
// Members:
/**
* @brief Fetches the current @e tied stream.
* @return A pointer to the tied stream, or NULL if the stream is
* not tied.
*
* A stream may be @e tied (or synchronized) to a second output
* stream. When this stream performs any I/O, the tied stream is
* first flushed. For example, @c std::cin is tied to @c std::cout.
*/
basic_ostream<_CharT, _Traits>*
tie() const
{ return _M_tie; }
/**
* @brief Ties this stream to an output stream.
* @param __tiestr The output stream.
* @return The previously tied output stream, or NULL if the stream
* was not tied.
*
* This sets up a new tie; see tie() for more.
*/
basic_ostream<_CharT, _Traits>*
tie(basic_ostream<_CharT, _Traits>* __tiestr)
{
basic_ostream<_CharT, _Traits>* __old = _M_tie;
_M_tie = __tiestr;
return __old;
}
/**
* @brief Accessing the underlying buffer.
* @return The current stream buffer.
*
* This does not change the state of the stream.
*/
basic_streambuf<_CharT, _Traits>*
rdbuf() const
{ return _M_streambuf; }
/**
* @brief Changing the underlying buffer.
* @param __sb The new stream buffer.
* @return The previous stream buffer.
*
* Associates a new buffer with the current stream, and clears the
* error state.
*
* Due to historical accidents which the LWG refuses to correct, the
* I/O library suffers from a design error: this function is hidden
* in derived classes by overrides of the zero-argument @c rdbuf(),
* which is non-virtual for hysterical raisins. As a result, you
* must use explicit qualifications to access this function via any
* derived class. For example:
*
* @code
* std::fstream foo; // or some other derived type
* std::streambuf* p = .....;
*
* foo.ios::rdbuf(p); // ios == basic_ios<char>
* @endcode
*/
basic_streambuf<_CharT, _Traits>*
rdbuf(basic_streambuf<_CharT, _Traits>* __sb);
/**
* @brief Copies fields of __rhs into this.
* @param __rhs The source values for the copies.
* @return Reference to this object.
*
* All fields of __rhs are copied into this object except that rdbuf()
* and rdstate() remain unchanged. All values in the pword and iword
* arrays are copied. Before copying, each callback is invoked with
* erase_event. After copying, each (new) callback is invoked with
* copyfmt_event. The final step is to copy exceptions().
*/
basic_ios&
copyfmt(const basic_ios& __rhs);
/**
* @brief Retrieves the @a empty character.
* @return The current fill character.
*
* It defaults to a space (' ') in the current locale.
*/
char_type
fill() const
{
if (!_M_fill_init)
{
_M_fill = this->widen(' ');
_M_fill_init = true;
}
return _M_fill;
}
/**
* @brief Sets a new @a empty character.
* @param __ch The new character.
* @return The previous fill character.
*
* The fill character is used to fill out space when P+ characters
* have been requested (e.g., via setw), Q characters are actually
* used, and Q<P. It defaults to a space (' ') in the current locale.
*/
char_type
fill(char_type __ch)
{
char_type __old = this->fill();
_M_fill = __ch;
return __old;
}
// Locales:
/**
* @brief Moves to a new locale.
* @param __loc The new locale.
* @return The previous locale.
*
* Calls @c ios_base::imbue(loc), and if a stream buffer is associated
* with this stream, calls that buffer's @c pubimbue(loc).
*
* Additional l10n notes are at
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
*/
locale
imbue(const locale& __loc);
/**
* @brief Squeezes characters.
* @param __c The character to narrow.
* @param __dfault The character to narrow.
* @return The narrowed character.
*
* Maps a character of @c char_type to a character of @c char,
* if possible.
*
* Returns the result of
* @code
* std::use_facet<ctype<char_type> >(getloc()).narrow(c,dfault)
* @endcode
*
* Additional l10n notes are at
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
*/
char
narrow(char_type __c, char __dfault) const
{ return __check_facet(_M_ctype).narrow(__c, __dfault); }
/**
* @brief Widens characters.
* @param __c The character to widen.
* @return The widened character.
*
* Maps a character of @c char to a character of @c char_type.
*
* Returns the result of
* @code
* std::use_facet<ctype<char_type> >(getloc()).widen(c)
* @endcode
*
* Additional l10n notes are at
* http://gcc.gnu.org/onlinedocs/libstdc++/manual/localization.html
*/
char_type
widen(char __c) const
{ return __check_facet(_M_ctype).widen(__c); }
protected:
// 27.4.5.1 basic_ios constructors
/**
* @brief Empty.
*
* The default constructor does nothing and is not normally
* accessible to users.
*/
basic_ios()
: ios_base(), _M_tie(0), _M_fill(char_type()), _M_fill_init(false),
_M_streambuf(0), _M_ctype(0), _M_num_put(0), _M_num_get(0)
{ }
/**
* @brief All setup is performed here.
*
* This is called from the public constructor. It is not virtual and
* cannot be redefined.
*/
void
init(basic_streambuf<_CharT, _Traits>* __sb);
#if __cplusplus >= 201103L
basic_ios(const basic_ios&) = delete;
basic_ios& operator=(const basic_ios&) = delete;
void
move(basic_ios& __rhs)
{
ios_base::_M_move(__rhs);
_M_cache_locale(_M_ios_locale);
this->tie(__rhs.tie(nullptr));
_M_fill = __rhs._M_fill;
_M_fill_init = __rhs._M_fill_init;
_M_streambuf = nullptr;
}
void
move(basic_ios&& __rhs)
{ this->move(__rhs); }
void
swap(basic_ios& __rhs) noexcept
{
ios_base::_M_swap(__rhs);
_M_cache_locale(_M_ios_locale);
__rhs._M_cache_locale(__rhs._M_ios_locale);
std::swap(_M_tie, __rhs._M_tie);
std::swap(_M_fill, __rhs._M_fill);
std::swap(_M_fill_init, __rhs._M_fill_init);
}
void
set_rdbuf(basic_streambuf<_CharT, _Traits>* __sb)
{ _M_streambuf = __sb; }
#endif
void
_M_cache_locale(const locale& __loc);
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#include <bits/basic_ios.tcc>
#endif /* _BASIC_IOS_H */

View File

@ -0,0 +1,188 @@
// basic_ios member functions -*- C++ -*-
// Copyright (C) 1999-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/basic_ios.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ios}
*/
#ifndef _BASIC_IOS_TCC
#define _BASIC_IOS_TCC 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _CharT, typename _Traits>
void
basic_ios<_CharT, _Traits>::clear(iostate __state)
{
if (this->rdbuf())
_M_streambuf_state = __state;
else
_M_streambuf_state = __state | badbit;
if (this->exceptions() & this->rdstate())
__throw_ios_failure(__N("basic_ios::clear"));
}
template<typename _CharT, typename _Traits>
basic_streambuf<_CharT, _Traits>*
basic_ios<_CharT, _Traits>::rdbuf(basic_streambuf<_CharT, _Traits>* __sb)
{
basic_streambuf<_CharT, _Traits>* __old = _M_streambuf;
_M_streambuf = __sb;
this->clear();
return __old;
}
template<typename _CharT, typename _Traits>
basic_ios<_CharT, _Traits>&
basic_ios<_CharT, _Traits>::copyfmt(const basic_ios& __rhs)
{
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 292. effects of a.copyfmt (a)
if (this != &__rhs)
{
// Per 27.1.1, do not call imbue, yet must trash all caches
// associated with imbue()
// Alloc any new word array first, so if it fails we have "rollback".
_Words* __words = (__rhs._M_word_size <= _S_local_word_size) ?
_M_local_word : new _Words[__rhs._M_word_size];
// Bump refs before doing callbacks, for safety.
_Callback_list* __cb = __rhs._M_callbacks;
if (__cb)
__cb->_M_add_reference();
_M_call_callbacks(erase_event);
if (_M_word != _M_local_word)
{
delete [] _M_word;
_M_word = 0;
}
_M_dispose_callbacks();
// NB: Don't want any added during above.
_M_callbacks = __cb;
for (int __i = 0; __i < __rhs._M_word_size; ++__i)
__words[__i] = __rhs._M_word[__i];
_M_word = __words;
_M_word_size = __rhs._M_word_size;
this->flags(__rhs.flags());
this->width(__rhs.width());
this->precision(__rhs.precision());
this->tie(__rhs.tie());
this->fill(__rhs.fill());
_M_ios_locale = __rhs.getloc();
_M_cache_locale(_M_ios_locale);
_M_call_callbacks(copyfmt_event);
// The next is required to be the last assignment.
this->exceptions(__rhs.exceptions());
}
return *this;
}
// Locales:
template<typename _CharT, typename _Traits>
locale
basic_ios<_CharT, _Traits>::imbue(const locale& __loc)
{
locale __old(this->getloc());
ios_base::imbue(__loc);
_M_cache_locale(__loc);
if (this->rdbuf() != 0)
this->rdbuf()->pubimbue(__loc);
return __old;
}
template<typename _CharT, typename _Traits>
void
basic_ios<_CharT, _Traits>::init(basic_streambuf<_CharT, _Traits>* __sb)
{
// NB: This may be called more than once on the same object.
ios_base::_M_init();
// Cache locale data and specific facets used by iostreams.
_M_cache_locale(_M_ios_locale);
// NB: The 27.4.4.1 Postconditions Table specifies requirements
// after basic_ios::init() has been called. As part of this,
// fill() must return widen(' ') any time after init() has been
// called, which needs an imbued ctype facet of char_type to
// return without throwing an exception. Unfortunately,
// ctype<char_type> is not necessarily a required facet, so
// streams with char_type != [char, wchar_t] will not have it by
// default. Because of this, the correct value for _M_fill is
// constructed on the first call of fill(). That way,
// unformatted input and output with non-required basic_ios
// instantiations is possible even without imbuing the expected
// ctype<char_type> facet.
_M_fill = _CharT();
_M_fill_init = false;
_M_tie = 0;
_M_exception = goodbit;
_M_streambuf = __sb;
_M_streambuf_state = __sb ? goodbit : badbit;
}
template<typename _CharT, typename _Traits>
void
basic_ios<_CharT, _Traits>::_M_cache_locale(const locale& __loc)
{
if (__builtin_expect(has_facet<__ctype_type>(__loc), true))
_M_ctype = std::__addressof(use_facet<__ctype_type>(__loc));
else
_M_ctype = 0;
if (__builtin_expect(has_facet<__num_put_type>(__loc), true))
_M_num_put = std::__addressof(use_facet<__num_put_type>(__loc));
else
_M_num_put = 0;
if (__builtin_expect(has_facet<__num_get_type>(__loc), true))
_M_num_get = std::__addressof(use_facet<__num_get_type>(__loc));
else
_M_num_get = 0;
}
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class basic_ios<char>;
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class basic_ios<wchar_t>;
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif

View File

@ -0,0 +1,794 @@
// -*- C++ -*-
// Copyright (C) 2004-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
// (C) Copyright Jeremy Siek 2000. Permission to copy, use, modify,
// sell and distribute this software is granted provided this
// copyright notice appears in all copies. This software is provided
// "as is" without express or implied warranty, and with no claim as
// to its suitability for any purpose.
//
/** @file bits/boost_concept_check.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
// GCC Note: based on version 1.12.0 of the Boost library.
#ifndef _BOOST_CONCEPT_CHECK_H
#define _BOOST_CONCEPT_CHECK_H 1
#pragma GCC system_header
#include <bits/c++config.h>
#include <bits/stl_iterator_base_types.h> // for traits and tags
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#define _IsUnused __attribute__ ((__unused__))
// When the C-C code is in use, we would like this function to do as little
// as possible at runtime, use as few resources as possible, and hopefully
// be elided out of existence... hmmm.
template <class _Concept>
_GLIBCXX14_CONSTEXPR inline void __function_requires()
{
void (_Concept::*__x)() _IsUnused = &_Concept::__constraints;
}
// No definition: if this is referenced, there's a problem with
// the instantiating type not being one of the required integer types.
// Unfortunately, this results in a link-time error, not a compile-time error.
void __error_type_must_be_an_integer_type();
void __error_type_must_be_an_unsigned_integer_type();
void __error_type_must_be_a_signed_integer_type();
// ??? Should the "concept_checking*" structs begin with more than _ ?
#define _GLIBCXX_CLASS_REQUIRES(_type_var, _ns, _concept) \
typedef void (_ns::_concept <_type_var>::* _func##_type_var##_concept)(); \
template <_func##_type_var##_concept _Tp1> \
struct _concept_checking##_type_var##_concept { }; \
typedef _concept_checking##_type_var##_concept< \
&_ns::_concept <_type_var>::__constraints> \
_concept_checking_typedef##_type_var##_concept
#define _GLIBCXX_CLASS_REQUIRES2(_type_var1, _type_var2, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2>::* _func##_type_var1##_type_var2##_concept)(); \
template <_func##_type_var1##_type_var2##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_concept< \
&_ns::_concept <_type_var1,_type_var2>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_concept
#define _GLIBCXX_CLASS_REQUIRES3(_type_var1, _type_var2, _type_var3, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3>::* _func##_type_var1##_type_var2##_type_var3##_concept)(); \
template <_func##_type_var1##_type_var2##_type_var3##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_type_var3##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_type_var3##_concept< \
&_ns::_concept <_type_var1,_type_var2,_type_var3>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_type_var3##_concept
#define _GLIBCXX_CLASS_REQUIRES4(_type_var1, _type_var2, _type_var3, _type_var4, _ns, _concept) \
typedef void (_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::* _func##_type_var1##_type_var2##_type_var3##_type_var4##_concept)(); \
template <_func##_type_var1##_type_var2##_type_var3##_type_var4##_concept _Tp1> \
struct _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept { }; \
typedef _concept_checking##_type_var1##_type_var2##_type_var3##_type_var4##_concept< \
&_ns::_concept <_type_var1,_type_var2,_type_var3,_type_var4>::__constraints> \
_concept_checking_typedef##_type_var1##_type_var2##_type_var3##_type_var4##_concept
template <class _Tp1, class _Tp2>
struct _Aux_require_same { };
template <class _Tp>
struct _Aux_require_same<_Tp,_Tp> { typedef _Tp _Type; };
template <class _Tp1, class _Tp2>
struct _SameTypeConcept
{
void __constraints() {
typedef typename _Aux_require_same<_Tp1, _Tp2>::_Type _Required;
}
};
template <class _Tp>
struct _IntegerConcept {
void __constraints() {
__error_type_must_be_an_integer_type();
}
};
template <> struct _IntegerConcept<short> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned short> { void __constraints(){} };
template <> struct _IntegerConcept<int> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned int> { void __constraints() {} };
template <> struct _IntegerConcept<long> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned long> { void __constraints() {} };
template <> struct _IntegerConcept<long long> { void __constraints() {} };
template <> struct _IntegerConcept<unsigned long long>
{ void __constraints() {} };
template <class _Tp>
struct _SignedIntegerConcept {
void __constraints() {
__error_type_must_be_a_signed_integer_type();
}
};
template <> struct _SignedIntegerConcept<short> { void __constraints() {} };
template <> struct _SignedIntegerConcept<int> { void __constraints() {} };
template <> struct _SignedIntegerConcept<long> { void __constraints() {} };
template <> struct _SignedIntegerConcept<long long> { void __constraints(){}};
template <class _Tp>
struct _UnsignedIntegerConcept {
void __constraints() {
__error_type_must_be_an_unsigned_integer_type();
}
};
template <> struct _UnsignedIntegerConcept<unsigned short>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned int>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned long>
{ void __constraints() {} };
template <> struct _UnsignedIntegerConcept<unsigned long long>
{ void __constraints() {} };
//===========================================================================
// Basic Concepts
template <class _Tp>
struct _DefaultConstructibleConcept
{
void __constraints() {
_Tp __a _IsUnused; // require default constructor
}
};
template <class _Tp>
struct _AssignableConcept
{
void __constraints() {
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
__a = __b; // const required for argument to assignment
}
_Tp __a;
// possibly should be "Tp* a;" and then dereference "a" in constraint
// functions? present way would require a default ctor, i think...
};
template <class _Tp>
struct _CopyConstructibleConcept
{
void __constraints() {
_Tp __a(__b); // require copy constructor
_Tp* __ptr _IsUnused = &__a; // require address of operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __a) {
_Tp __c _IsUnused(__a); // require const copy constructor
const _Tp* __ptr _IsUnused = &__a; // require const address of operator
}
_Tp __b;
};
// The SGI STL version of Assignable requires copy constructor and operator=
template <class _Tp>
struct _SGIAssignableConcept
{
void __constraints() {
_Tp __b _IsUnused(__a);
__a = __a; // require assignment operator
__const_constraints(__a);
}
void __const_constraints(const _Tp& __b) {
_Tp __c _IsUnused(__b);
__a = __b; // const required for argument to assignment
}
_Tp __a;
};
template <class _From, class _To>
struct _ConvertibleConcept
{
void __constraints() {
_To __y _IsUnused = __x;
}
_From __x;
};
// The C++ standard requirements for many concepts talk about return
// types that must be "convertible to bool". The problem with this
// requirement is that it leaves the door open for evil proxies that
// define things like operator|| with strange return types. Two
// possible solutions are:
// 1) require the return type to be exactly bool
// 2) stay with convertible to bool, and also
// specify stuff about all the logical operators.
// For now we just test for convertible to bool.
template <class _Tp>
void __aux_require_boolean_expr(const _Tp& __t) {
bool __x _IsUnused = __t;
}
// FIXME
template <class _Tp>
struct _EqualityComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a == __b);
}
_Tp __a, __b;
};
template <class _Tp>
struct _LessThanComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a < __b);
}
_Tp __a, __b;
};
// This is equivalent to SGI STL's LessThanComparable.
template <class _Tp>
struct _ComparableConcept
{
void __constraints() {
__aux_require_boolean_expr(__a < __b);
__aux_require_boolean_expr(__a > __b);
__aux_require_boolean_expr(__a <= __b);
__aux_require_boolean_expr(__a >= __b);
}
_Tp __a, __b;
};
#define _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(_OP,_NAME) \
template <class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
bool __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
#define _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(_OP,_NAME) \
template <class _Ret, class _First, class _Second> \
struct _NAME { \
void __constraints() { (void)__constraints_(); } \
_Ret __constraints_() { \
return __a _OP __b; \
} \
_First __a; \
_Second __b; \
}
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(==, _EqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(!=, _NotEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<, _LessThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(<=, _LessEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>, _GreaterThanOpConcept);
_GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT(>=, _GreaterEqualOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(+, _PlusOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(*, _TimesOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(/, _DivideOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(-, _SubtractOpConcept);
_GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT(%, _ModOpConcept);
#undef _GLIBCXX_DEFINE_BINARY_PREDICATE_OP_CONSTRAINT
#undef _GLIBCXX_DEFINE_BINARY_OPERATOR_CONSTRAINT
//===========================================================================
// Function Object Concepts
template <class _Func, class _Return>
struct _GeneratorConcept
{
void __constraints() {
const _Return& __r _IsUnused = __f();// require operator() member function
}
_Func __f;
};
template <class _Func>
struct _GeneratorConcept<_Func,void>
{
void __constraints() {
__f(); // require operator() member function
}
_Func __f;
};
template <class _Func, class _Return, class _Arg>
struct _UnaryFunctionConcept
{
void __constraints() {
__r = __f(__arg); // require operator()
}
_Func __f;
_Arg __arg;
_Return __r;
};
template <class _Func, class _Arg>
struct _UnaryFunctionConcept<_Func, void, _Arg> {
void __constraints() {
__f(__arg); // require operator()
}
_Func __f;
_Arg __arg;
};
template <class _Func, class _Return, class _First, class _Second>
struct _BinaryFunctionConcept
{
void __constraints() {
__r = __f(__first, __second); // require operator()
}
_Func __f;
_First __first;
_Second __second;
_Return __r;
};
template <class _Func, class _First, class _Second>
struct _BinaryFunctionConcept<_Func, void, _First, _Second>
{
void __constraints() {
__f(__first, __second); // require operator()
}
_Func __f;
_First __first;
_Second __second;
};
template <class _Func, class _Arg>
struct _UnaryPredicateConcept
{
void __constraints() {
__aux_require_boolean_expr(__f(__arg)); // require op() returning bool
}
_Func __f;
_Arg __arg;
};
template <class _Func, class _First, class _Second>
struct _BinaryPredicateConcept
{
void __constraints() {
__aux_require_boolean_expr(__f(__a, __b)); // require op() returning bool
}
_Func __f;
_First __a;
_Second __b;
};
// use this when functor is used inside a container class like std::set
template <class _Func, class _First, class _Second>
struct _Const_BinaryPredicateConcept {
void __constraints() {
__const_constraints(__f);
}
void __const_constraints(const _Func& __fun) {
__function_requires<_BinaryPredicateConcept<_Func, _First, _Second> >();
// operator() must be a const member function
__aux_require_boolean_expr(__fun(__a, __b));
}
_Func __f;
_First __a;
_Second __b;
};
//===========================================================================
// Iterator Concepts
template <class _Tp>
struct _TrivialIteratorConcept
{
void __constraints() {
// __function_requires< _DefaultConstructibleConcept<_Tp> >();
__function_requires< _AssignableConcept<_Tp> >();
__function_requires< _EqualityComparableConcept<_Tp> >();
// typedef typename std::iterator_traits<_Tp>::value_type _V;
(void)*__i; // require dereference operator
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_TrivialIteratorConcept
{
void __constraints() {
__function_requires< _TrivialIteratorConcept<_Tp> >();
*__i = *__j; // require dereference and assignment
}
_Tp __i, __j;
};
template <class _Tp>
struct _InputIteratorConcept
{
void __constraints() {
__function_requires< _TrivialIteratorConcept<_Tp> >();
// require iterator_traits typedef's
typedef typename std::iterator_traits<_Tp>::difference_type _Diff;
// __function_requires< _SignedIntegerConcept<_Diff> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
typedef typename std::iterator_traits<_Tp>::pointer _Pt;
typedef typename std::iterator_traits<_Tp>::iterator_category _Cat;
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::input_iterator_tag> >();
++__i; // require preincrement operator
__i++; // require postincrement operator
}
_Tp __i;
};
template <class _Tp, class _ValueT>
struct _OutputIteratorConcept
{
void __constraints() {
__function_requires< _AssignableConcept<_Tp> >();
++__i; // require preincrement operator
__i++; // require postincrement operator
*__i++ = __t; // require postincrement and assignment
}
_Tp __i;
_ValueT __t;
};
template <class _Tp>
struct _ForwardIteratorConcept
{
void __constraints() {
__function_requires< _InputIteratorConcept<_Tp> >();
__function_requires< _DefaultConstructibleConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::forward_iterator_tag> >();
typedef typename std::iterator_traits<_Tp>::reference _Ref;
_Ref __r _IsUnused = *__i;
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_ForwardIteratorConcept
{
void __constraints() {
__function_requires< _ForwardIteratorConcept<_Tp> >();
*__i++ = *__i; // require postincrement and assignment
}
_Tp __i;
};
template <class _Tp>
struct _BidirectionalIteratorConcept
{
void __constraints() {
__function_requires< _ForwardIteratorConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::bidirectional_iterator_tag> >();
--__i; // require predecrement operator
__i--; // require postdecrement operator
}
_Tp __i;
};
template <class _Tp>
struct _Mutable_BidirectionalIteratorConcept
{
void __constraints() {
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
__function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
*__i-- = *__i; // require postdecrement and assignment
}
_Tp __i;
};
template <class _Tp>
struct _RandomAccessIteratorConcept
{
void __constraints() {
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
__function_requires< _ComparableConcept<_Tp> >();
__function_requires< _ConvertibleConcept<
typename std::iterator_traits<_Tp>::iterator_category,
std::random_access_iterator_tag> >();
// ??? We don't use _Ref, are we just checking for "referenceability"?
typedef typename std::iterator_traits<_Tp>::reference _Ref;
__i += __n; // require assignment addition operator
__i = __i + __n; __i = __n + __i; // require addition with difference type
__i -= __n; // require assignment subtraction op
__i = __i - __n; // require subtraction with
// difference type
__n = __i - __j; // require difference operator
(void)__i[__n]; // require element access operator
}
_Tp __a, __b;
_Tp __i, __j;
typename std::iterator_traits<_Tp>::difference_type __n;
};
template <class _Tp>
struct _Mutable_RandomAccessIteratorConcept
{
void __constraints() {
__function_requires< _RandomAccessIteratorConcept<_Tp> >();
__function_requires< _Mutable_BidirectionalIteratorConcept<_Tp> >();
__i[__n] = *__i; // require element access and assignment
}
_Tp __i;
typename std::iterator_traits<_Tp>::difference_type __n;
};
//===========================================================================
// Container Concepts
template <class _Container>
struct _ContainerConcept
{
typedef typename _Container::value_type _Value_type;
typedef typename _Container::difference_type _Difference_type;
typedef typename _Container::size_type _Size_type;
typedef typename _Container::const_reference _Const_reference;
typedef typename _Container::const_pointer _Const_pointer;
typedef typename _Container::const_iterator _Const_iterator;
void __constraints() {
__function_requires< _InputIteratorConcept<_Const_iterator> >();
__function_requires< _AssignableConcept<_Container> >();
const _Container __c;
__i = __c.begin();
__i = __c.end();
__n = __c.size();
__n = __c.max_size();
__b = __c.empty();
}
bool __b;
_Const_iterator __i;
_Size_type __n;
};
template <class _Container>
struct _Mutable_ContainerConcept
{
typedef typename _Container::value_type _Value_type;
typedef typename _Container::reference _Reference;
typedef typename _Container::iterator _Iterator;
typedef typename _Container::pointer _Pointer;
void __constraints() {
__function_requires< _ContainerConcept<_Container> >();
__function_requires< _AssignableConcept<_Value_type> >();
__function_requires< _InputIteratorConcept<_Iterator> >();
__i = __c.begin();
__i = __c.end();
__c.swap(__c2);
}
_Iterator __i;
_Container __c, __c2;
};
template <class _ForwardContainer>
struct _ForwardContainerConcept
{
void __constraints() {
__function_requires< _ContainerConcept<_ForwardContainer> >();
typedef typename _ForwardContainer::const_iterator _Const_iterator;
__function_requires< _ForwardIteratorConcept<_Const_iterator> >();
}
};
template <class _ForwardContainer>
struct _Mutable_ForwardContainerConcept
{
void __constraints() {
__function_requires< _ForwardContainerConcept<_ForwardContainer> >();
__function_requires< _Mutable_ContainerConcept<_ForwardContainer> >();
typedef typename _ForwardContainer::iterator _Iterator;
__function_requires< _Mutable_ForwardIteratorConcept<_Iterator> >();
}
};
template <class _ReversibleContainer>
struct _ReversibleContainerConcept
{
typedef typename _ReversibleContainer::const_iterator _Const_iterator;
typedef typename _ReversibleContainer::const_reverse_iterator
_Const_reverse_iterator;
void __constraints() {
__function_requires< _ForwardContainerConcept<_ReversibleContainer> >();
__function_requires< _BidirectionalIteratorConcept<_Const_iterator> >();
__function_requires<
_BidirectionalIteratorConcept<_Const_reverse_iterator> >();
const _ReversibleContainer __c;
_Const_reverse_iterator __i = __c.rbegin();
__i = __c.rend();
}
};
template <class _ReversibleContainer>
struct _Mutable_ReversibleContainerConcept
{
typedef typename _ReversibleContainer::iterator _Iterator;
typedef typename _ReversibleContainer::reverse_iterator _Reverse_iterator;
void __constraints() {
__function_requires<_ReversibleContainerConcept<_ReversibleContainer> >();
__function_requires<
_Mutable_ForwardContainerConcept<_ReversibleContainer> >();
__function_requires<_Mutable_BidirectionalIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_BidirectionalIteratorConcept<_Reverse_iterator> >();
_Reverse_iterator __i = __c.rbegin();
__i = __c.rend();
}
_ReversibleContainer __c;
};
template <class _RandomAccessContainer>
struct _RandomAccessContainerConcept
{
typedef typename _RandomAccessContainer::size_type _Size_type;
typedef typename _RandomAccessContainer::const_reference _Const_reference;
typedef typename _RandomAccessContainer::const_iterator _Const_iterator;
typedef typename _RandomAccessContainer::const_reverse_iterator
_Const_reverse_iterator;
void __constraints() {
__function_requires<
_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _RandomAccessIteratorConcept<_Const_iterator> >();
__function_requires<
_RandomAccessIteratorConcept<_Const_reverse_iterator> >();
const _RandomAccessContainer __c;
_Const_reference __r _IsUnused = __c[__n];
}
_Size_type __n;
};
template <class _RandomAccessContainer>
struct _Mutable_RandomAccessContainerConcept
{
typedef typename _RandomAccessContainer::size_type _Size_type;
typedef typename _RandomAccessContainer::reference _Reference;
typedef typename _RandomAccessContainer::iterator _Iterator;
typedef typename _RandomAccessContainer::reverse_iterator _Reverse_iterator;
void __constraints() {
__function_requires<
_RandomAccessContainerConcept<_RandomAccessContainer> >();
__function_requires<
_Mutable_ReversibleContainerConcept<_RandomAccessContainer> >();
__function_requires< _Mutable_RandomAccessIteratorConcept<_Iterator> >();
__function_requires<
_Mutable_RandomAccessIteratorConcept<_Reverse_iterator> >();
_Reference __r _IsUnused = __c[__i];
}
_Size_type __i;
_RandomAccessContainer __c;
};
// A Sequence is inherently mutable
template <class _Sequence>
struct _SequenceConcept
{
typedef typename _Sequence::reference _Reference;
typedef typename _Sequence::const_reference _Const_reference;
void __constraints() {
// Matt Austern's book puts DefaultConstructible here, the C++
// standard places it in Container
// function_requires< DefaultConstructible<Sequence> >();
__function_requires< _Mutable_ForwardContainerConcept<_Sequence> >();
__function_requires< _DefaultConstructibleConcept<_Sequence> >();
_Sequence
__c _IsUnused(__n, __t),
__c2 _IsUnused(__first, __last);
__c.insert(__p, __t);
__c.insert(__p, __n, __t);
__c.insert(__p, __first, __last);
__c.erase(__p);
__c.erase(__p, __q);
_Reference __r _IsUnused = __c.front();
__const_constraints(__c);
}
void __const_constraints(const _Sequence& __c) {
_Const_reference __r _IsUnused = __c.front();
}
typename _Sequence::value_type __t;
typename _Sequence::size_type __n;
typename _Sequence::value_type *__first, *__last;
typename _Sequence::iterator __p, __q;
};
template <class _FrontInsertionSequence>
struct _FrontInsertionSequenceConcept
{
void __constraints() {
__function_requires< _SequenceConcept<_FrontInsertionSequence> >();
__c.push_front(__t);
__c.pop_front();
}
_FrontInsertionSequence __c;
typename _FrontInsertionSequence::value_type __t;
};
template <class _BackInsertionSequence>
struct _BackInsertionSequenceConcept
{
typedef typename _BackInsertionSequence::reference _Reference;
typedef typename _BackInsertionSequence::const_reference _Const_reference;
void __constraints() {
__function_requires< _SequenceConcept<_BackInsertionSequence> >();
__c.push_back(__t);
__c.pop_back();
_Reference __r _IsUnused = __c.back();
}
void __const_constraints(const _BackInsertionSequence& __c) {
_Const_reference __r _IsUnused = __c.back();
};
_BackInsertionSequence __c;
typename _BackInsertionSequence::value_type __t;
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#pragma GCC diagnostic pop
#undef _IsUnused
#endif // _GLIBCXX_BOOST_CONCEPT_CHECK

View File

@ -0,0 +1,37 @@
// Copyright (C) 2007-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/c++0x_warning.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iosfwd}
*/
#ifndef _CXX0X_WARNING_H
#define _CXX0X_WARNING_H 1
#if __cplusplus < 201103L
#error This file requires compiler and library support \
for the ISO C++ 2011 standard. This support must be enabled \
with the -std=c++11 or -std=gnu++11 compiler options.
#endif
#endif

View File

@ -0,0 +1,957 @@
// Character Traits for use by standard string and iostream -*- C++ -*-
// Copyright (C) 1997-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/char_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{string}
*/
//
// ISO C++ 14882: 21 Strings library
//
#ifndef _CHAR_TRAITS_H
#define _CHAR_TRAITS_H 1
#pragma GCC system_header
#include <bits/stl_algobase.h> // std::copy, std::fill_n
#include <bits/postypes.h> // For streampos
#include <cwchar> // For WEOF, wmemmove, wmemset, etc.
#if __cplusplus > 201703L
# include <compare>
#endif
#ifndef _GLIBCXX_ALWAYS_INLINE
# define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
#endif
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Mapping from character type to associated types.
*
* @note This is an implementation class for the generic version
* of char_traits. It defines int_type, off_type, pos_type, and
* state_type. By default these are unsigned long, streamoff,
* streampos, and mbstate_t. Users who need a different set of
* types, but who don't need to change the definitions of any function
* defined in char_traits, can specialize __gnu_cxx::_Char_types
* while leaving __gnu_cxx::char_traits alone. */
template<typename _CharT>
struct _Char_types
{
typedef unsigned long int_type;
typedef std::streampos pos_type;
typedef std::streamoff off_type;
typedef std::mbstate_t state_type;
};
/**
* @brief Base class used to implement std::char_traits.
*
* @note For any given actual character type, this definition is
* probably wrong. (Most of the member functions are likely to be
* right, but the int_type and state_type typedefs, and the eof()
* member function, are likely to be wrong.) The reason this class
* exists is so users can specialize it. Classes in namespace std
* may not be specialized for fundamental types, but classes in
* namespace __gnu_cxx may be.
*
* See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
* for advice on how to make use of this class for @a unusual character
* types. Also, check out include/ext/pod_char_traits.h.
*/
template<typename _CharT>
struct char_traits
{
typedef _CharT char_type;
typedef typename _Char_types<_CharT>::int_type int_type;
typedef typename _Char_types<_CharT>::pos_type pos_type;
typedef typename _Char_types<_CharT>::off_type off_type;
typedef typename _Char_types<_CharT>::state_type state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = std::strong_ordering;
#endif
static _GLIBCXX14_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2)
{ __c1 = __c2; }
static _GLIBCXX_CONSTEXPR bool
eq(const char_type& __c1, const char_type& __c2)
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR bool
lt(const char_type& __c1, const char_type& __c2)
{ return __c1 < __c2; }
static _GLIBCXX14_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
static _GLIBCXX14_CONSTEXPR std::size_t
length(const char_type* __s);
static _GLIBCXX14_CONSTEXPR const char_type*
find(const char_type* __s, std::size_t __n, const char_type& __a);
static _GLIBCXX20_CONSTEXPR char_type*
move(char_type* __s1, const char_type* __s2, std::size_t __n);
static _GLIBCXX20_CONSTEXPR char_type*
copy(char_type* __s1, const char_type* __s2, std::size_t __n);
static _GLIBCXX20_CONSTEXPR char_type*
assign(char_type* __s, std::size_t __n, char_type __a);
static _GLIBCXX_CONSTEXPR char_type
to_char_type(const int_type& __c)
{ return static_cast<char_type>(__c); }
static _GLIBCXX_CONSTEXPR int_type
to_int_type(const char_type& __c)
{ return static_cast<int_type>(__c); }
static _GLIBCXX_CONSTEXPR bool
eq_int_type(const int_type& __c1, const int_type& __c2)
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR int_type
eof()
{ return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
static _GLIBCXX_CONSTEXPR int_type
not_eof(const int_type& __c)
{ return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
};
template<typename _CharT>
_GLIBCXX14_CONSTEXPR int
char_traits<_CharT>::
compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
{
for (std::size_t __i = 0; __i < __n; ++__i)
if (lt(__s1[__i], __s2[__i]))
return -1;
else if (lt(__s2[__i], __s1[__i]))
return 1;
return 0;
}
template<typename _CharT>
_GLIBCXX14_CONSTEXPR std::size_t
char_traits<_CharT>::
length(const char_type* __p)
{
std::size_t __i = 0;
while (!eq(__p[__i], char_type()))
++__i;
return __i;
}
template<typename _CharT>
_GLIBCXX14_CONSTEXPR const typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
find(const char_type* __s, std::size_t __n, const char_type& __a)
{
for (std::size_t __i = 0; __i < __n; ++__i)
if (eq(__s[__i], __a))
return __s + __i;
return 0;
}
template<typename _CharT>
_GLIBCXX20_CONSTEXPR
typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
move(char_type* __s1, const char_type* __s2, std::size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
{
if (__s1 > __s2 && __s1 < __s2 + __n)
std::copy_backward(__s2, __s2 + __n, __s1 + __n);
else
std::copy(__s2, __s2 + __n, __s1);
return __s1;
}
#endif
return static_cast<_CharT*>(__builtin_memmove(__s1, __s2,
__n * sizeof(char_type)));
}
template<typename _CharT>
_GLIBCXX20_CONSTEXPR
typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
copy(char_type* __s1, const char_type* __s2, std::size_t __n)
{
// NB: Inline std::copy so no recursive dependencies.
std::copy(__s2, __s2 + __n, __s1);
return __s1;
}
template<typename _CharT>
_GLIBCXX20_CONSTEXPR
typename char_traits<_CharT>::char_type*
char_traits<_CharT>::
assign(char_type* __s, std::size_t __n, char_type __a)
{
// NB: Inline std::fill_n so no recursive dependencies.
std::fill_n(__s, __n, __a);
return __s;
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus >= 201703L
#ifdef __cpp_lib_is_constant_evaluated
// Unofficial macro indicating P1032R1 support in C++20
# define __cpp_lib_constexpr_char_traits 201811L
#else
// Unofficial macro indicating P0426R1 support in C++17
# define __cpp_lib_constexpr_char_traits 201611L
#endif
/**
* @brief Determine whether the characters of a NULL-terminated
* string are known at compile time.
* @param __s The string.
*
* Assumes that _CharT is a built-in character type.
*/
template<typename _CharT>
_GLIBCXX_ALWAYS_INLINE constexpr bool
__constant_string_p(const _CharT* __s)
{
#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
(void) __s;
// In constexpr contexts all strings should be constant.
return __builtin_is_constant_evaluated();
#else
while (__builtin_constant_p(*__s) && *__s)
__s++;
return __builtin_constant_p(*__s);
#endif
}
/**
* @brief Determine whether the characters of a character array are
* known at compile time.
* @param __a The character array.
* @param __n Number of characters.
*
* Assumes that _CharT is a built-in character type.
*/
template<typename _CharT>
_GLIBCXX_ALWAYS_INLINE constexpr bool
__constant_char_array_p(const _CharT* __a, size_t __n)
{
#ifdef _GLIBCXX_HAVE_BUILTIN_IS_CONSTANT_EVALUATED
(void) __a;
(void) __n;
// In constexpr contexts all character arrays should be constant.
return __builtin_is_constant_evaluated();
#else
size_t __i = 0;
while (__i < __n && __builtin_constant_p(__a[__i]))
__i++;
return __i == __n;
#endif
}
#endif
// 21.1
/**
* @brief Basis for explicit traits specializations.
*
* @note For any given actual character type, this definition is
* probably wrong. Since this is just a thin wrapper around
* __gnu_cxx::char_traits, it is possible to achieve a more
* appropriate definition by specializing __gnu_cxx::char_traits.
*
* See https://gcc.gnu.org/onlinedocs/libstdc++/manual/strings.html#strings.string.character_types
* for advice on how to make use of this class for @a unusual character
* types. Also, check out include/ext/pod_char_traits.h.
*/
template<class _CharT>
struct char_traits : public __gnu_cxx::char_traits<_CharT>
{ };
/// 21.1.3.1 char_traits specializations
template<>
struct char_traits<char>
{
typedef char char_type;
typedef int int_type;
typedef streampos pos_type;
typedef streamoff off_type;
typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ __c1 = __c2; }
static _GLIBCXX_CONSTEXPR bool
eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR bool
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{
// LWG 467.
return (static_cast<unsigned char>(__c1)
< static_cast<unsigned char>(__c2));
}
static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return 0;
#if __cplusplus >= 201703L
if (__builtin_constant_p(__n)
&& __constant_char_array_p(__s1, __n)
&& __constant_char_array_p(__s2, __n))
{
for (size_t __i = 0; __i < __n; ++__i)
if (lt(__s1[__i], __s2[__i]))
return -1;
else if (lt(__s2[__i], __s1[__i]))
return 1;
return 0;
}
#endif
return __builtin_memcmp(__s1, __s2, __n);
}
static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
#if __cplusplus >= 201703L
if (__constant_string_p(__s))
return __gnu_cxx::char_traits<char_type>::length(__s);
#endif
return __builtin_strlen(__s);
}
static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
if (__n == 0)
return 0;
#if __cplusplus >= 201703L
if (__builtin_constant_p(__n)
&& __builtin_constant_p(__a)
&& __constant_char_array_p(__s, __n))
return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
#endif
return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
}
static _GLIBCXX20_CONSTEXPR char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
#endif
return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
}
static _GLIBCXX20_CONSTEXPR char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
#endif
return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
}
static _GLIBCXX20_CONSTEXPR char_type*
assign(char_type* __s, size_t __n, char_type __a)
{
if (__n == 0)
return __s;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
#endif
return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
}
static _GLIBCXX_CONSTEXPR char_type
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return static_cast<char_type>(__c); }
// To keep both the byte 0xff and the eof symbol 0xffffffff
// from ending up as 0xffffffff.
static _GLIBCXX_CONSTEXPR int_type
to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
{ return static_cast<int_type>(static_cast<unsigned char>(__c)); }
static _GLIBCXX_CONSTEXPR bool
eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR int_type
eof() _GLIBCXX_NOEXCEPT
{ return static_cast<int_type>(_GLIBCXX_STDIO_EOF); }
static _GLIBCXX_CONSTEXPR int_type
not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return (__c == eof()) ? 0 : __c; }
};
#ifdef _GLIBCXX_USE_WCHAR_T
/// 21.1.3.2 char_traits specializations
template<>
struct char_traits<wchar_t>
{
typedef wchar_t char_type;
typedef wint_t int_type;
typedef streamoff off_type;
typedef wstreampos pos_type;
typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ __c1 = __c2; }
static _GLIBCXX_CONSTEXPR bool
eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR bool
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 < __c2; }
static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return 0;
#if __cplusplus >= 201703L
if (__builtin_constant_p(__n)
&& __constant_char_array_p(__s1, __n)
&& __constant_char_array_p(__s2, __n))
return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
#endif
return wmemcmp(__s1, __s2, __n);
}
static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
#if __cplusplus >= 201703L
if (__constant_string_p(__s))
return __gnu_cxx::char_traits<char_type>::length(__s);
#endif
return wcslen(__s);
}
static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
if (__n == 0)
return 0;
#if __cplusplus >= 201703L
if (__builtin_constant_p(__n)
&& __builtin_constant_p(__a)
&& __constant_char_array_p(__s, __n))
return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
#endif
return wmemchr(__s, __a, __n);
}
static _GLIBCXX20_CONSTEXPR char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
#endif
return wmemmove(__s1, __s2, __n);
}
static _GLIBCXX20_CONSTEXPR char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
#endif
return wmemcpy(__s1, __s2, __n);
}
static _GLIBCXX20_CONSTEXPR char_type*
assign(char_type* __s, size_t __n, char_type __a)
{
if (__n == 0)
return __s;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
#endif
return wmemset(__s, __a, __n);
}
static _GLIBCXX_CONSTEXPR char_type
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return char_type(__c); }
static _GLIBCXX_CONSTEXPR int_type
to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
{ return int_type(__c); }
static _GLIBCXX_CONSTEXPR bool
eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR int_type
eof() _GLIBCXX_NOEXCEPT
{ return static_cast<int_type>(WEOF); }
static _GLIBCXX_CONSTEXPR int_type
not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return eq_int_type(__c, eof()) ? 0 : __c; }
};
#endif //_GLIBCXX_USE_WCHAR_T
#ifdef _GLIBCXX_USE_CHAR8_T
template<>
struct char_traits<char8_t>
{
typedef char8_t char_type;
typedef unsigned int int_type;
typedef u8streampos pos_type;
typedef streamoff off_type;
typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ __c1 = __c2; }
static _GLIBCXX_CONSTEXPR bool
eq(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR bool
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 < __c2; }
static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return 0;
#if __cplusplus > 201402
if (__builtin_constant_p(__n)
&& __constant_char_array_p(__s1, __n)
&& __constant_char_array_p(__s2, __n))
return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
#endif
return __builtin_memcmp(__s1, __s2, __n);
}
static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
#if __cplusplus > 201402
if (__constant_string_p(__s))
return __gnu_cxx::char_traits<char_type>::length(__s);
#endif
size_t __i = 0;
while (!eq(__s[__i], char_type()))
++__i;
return __i;
}
static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
if (__n == 0)
return 0;
#if __cplusplus > 201402
if (__builtin_constant_p(__n)
&& __builtin_constant_p(__a)
&& __constant_char_array_p(__s, __n))
return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
#endif
return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
}
static _GLIBCXX20_CONSTEXPR char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
#endif
return static_cast<char_type*>(__builtin_memmove(__s1, __s2, __n));
}
static _GLIBCXX20_CONSTEXPR char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
#endif
return static_cast<char_type*>(__builtin_memcpy(__s1, __s2, __n));
}
static _GLIBCXX20_CONSTEXPR char_type*
assign(char_type* __s, size_t __n, char_type __a)
{
if (__n == 0)
return __s;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::assign(__s, __n, __a);
#endif
return static_cast<char_type*>(__builtin_memset(__s, __a, __n));
}
static _GLIBCXX_CONSTEXPR char_type
to_char_type(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return char_type(__c); }
static _GLIBCXX_CONSTEXPR int_type
to_int_type(const char_type& __c) _GLIBCXX_NOEXCEPT
{ return int_type(__c); }
static _GLIBCXX_CONSTEXPR bool
eq_int_type(const int_type& __c1, const int_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 == __c2; }
static _GLIBCXX_CONSTEXPR int_type
eof() _GLIBCXX_NOEXCEPT
{ return static_cast<int_type>(-1); }
static _GLIBCXX_CONSTEXPR int_type
not_eof(const int_type& __c) _GLIBCXX_NOEXCEPT
{ return eq_int_type(__c, eof()) ? 0 : __c; }
};
#endif //_GLIBCXX_USE_CHAR8_T
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#if __cplusplus >= 201103L
#include <cstdint>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
template<>
struct char_traits<char16_t>
{
typedef char16_t char_type;
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
typedef uint_least16_t int_type;
#elif defined __UINT_LEAST16_TYPE__
typedef __UINT_LEAST16_TYPE__ int_type;
#else
typedef make_unsigned<char16_t>::type int_type;
#endif
typedef streamoff off_type;
typedef u16streampos pos_type;
typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept
{ __c1 = __c2; }
static constexpr bool
eq(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 == __c2; }
static constexpr bool
lt(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 < __c2; }
static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
for (size_t __i = 0; __i < __n; ++__i)
if (lt(__s1[__i], __s2[__i]))
return -1;
else if (lt(__s2[__i], __s1[__i]))
return 1;
return 0;
}
static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
size_t __i = 0;
while (!eq(__s[__i], char_type()))
++__i;
return __i;
}
static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
for (size_t __i = 0; __i < __n; ++__i)
if (eq(__s[__i], __a))
return __s + __i;
return 0;
}
static _GLIBCXX20_CONSTEXPR char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
#endif
return (static_cast<char_type*>
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
}
static _GLIBCXX20_CONSTEXPR char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
#endif
return (static_cast<char_type*>
(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
}
static _GLIBCXX20_CONSTEXPR char_type*
assign(char_type* __s, size_t __n, char_type __a)
{
for (size_t __i = 0; __i < __n; ++__i)
assign(__s[__i], __a);
return __s;
}
static constexpr char_type
to_char_type(const int_type& __c) noexcept
{ return char_type(__c); }
static constexpr int_type
to_int_type(const char_type& __c) noexcept
{ return __c == eof() ? int_type(0xfffd) : int_type(__c); }
static constexpr bool
eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
{ return __c1 == __c2; }
static constexpr int_type
eof() noexcept
{ return static_cast<int_type>(-1); }
static constexpr int_type
not_eof(const int_type& __c) noexcept
{ return eq_int_type(__c, eof()) ? 0 : __c; }
};
template<>
struct char_traits<char32_t>
{
typedef char32_t char_type;
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
typedef uint_least32_t int_type;
#elif defined __UINT_LEAST32_TYPE__
typedef __UINT_LEAST32_TYPE__ int_type;
#else
typedef make_unsigned<char32_t>::type int_type;
#endif
typedef streamoff off_type;
typedef u32streampos pos_type;
typedef mbstate_t state_type;
#if __cpp_lib_three_way_comparison
using comparison_category = strong_ordering;
#endif
static _GLIBCXX17_CONSTEXPR void
assign(char_type& __c1, const char_type& __c2) noexcept
{ __c1 = __c2; }
static constexpr bool
eq(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 == __c2; }
static constexpr bool
lt(const char_type& __c1, const char_type& __c2) noexcept
{ return __c1 < __c2; }
static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
for (size_t __i = 0; __i < __n; ++__i)
if (lt(__s1[__i], __s2[__i]))
return -1;
else if (lt(__s2[__i], __s1[__i]))
return 1;
return 0;
}
static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
{
size_t __i = 0;
while (!eq(__s[__i], char_type()))
++__i;
return __i;
}
static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
for (size_t __i = 0; __i < __n; ++__i)
if (eq(__s[__i], __a))
return __s + __i;
return 0;
}
static _GLIBCXX20_CONSTEXPR char_type*
move(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::move(__s1, __s2, __n);
#endif
return (static_cast<char_type*>
(__builtin_memmove(__s1, __s2, __n * sizeof(char_type))));
}
static _GLIBCXX20_CONSTEXPR char_type*
copy(char_type* __s1, const char_type* __s2, size_t __n)
{
if (__n == 0)
return __s1;
#ifdef __cpp_lib_is_constant_evaluated
if (std::is_constant_evaluated())
return __gnu_cxx::char_traits<char_type>::copy(__s1, __s2, __n);
#endif
return (static_cast<char_type*>
(__builtin_memcpy(__s1, __s2, __n * sizeof(char_type))));
}
static _GLIBCXX20_CONSTEXPR char_type*
assign(char_type* __s, size_t __n, char_type __a)
{
for (size_t __i = 0; __i < __n; ++__i)
assign(__s[__i], __a);
return __s;
}
static constexpr char_type
to_char_type(const int_type& __c) noexcept
{ return char_type(__c); }
static constexpr int_type
to_int_type(const char_type& __c) noexcept
{ return int_type(__c); }
static constexpr bool
eq_int_type(const int_type& __c1, const int_type& __c2) noexcept
{ return __c1 == __c2; }
static constexpr int_type
eof() noexcept
{ return static_cast<int_type>(-1); }
static constexpr int_type
not_eof(const int_type& __c) noexcept
{ return eq_int_type(__c, eof()) ? 0 : __c; }
};
#if __cpp_lib_three_way_comparison
namespace __detail
{
template<typename _ChTraits>
constexpr auto
__char_traits_cmp_cat(int __cmp) noexcept
{
if constexpr (requires { typename _ChTraits::comparison_category; })
{
using _Cat = typename _ChTraits::comparison_category;
static_assert( !is_void_v<common_comparison_category_t<_Cat>> );
return static_cast<_Cat>(__cmp <=> 0);
}
else
return static_cast<weak_ordering>(__cmp <=> 0);
}
} // namespace __detail
#endif // C++20
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // C++11
#endif // _CHAR_TRAITS_H

View File

@ -0,0 +1,106 @@
// Numeric conversions (to_string, to_chars) -*- C++ -*-
// Copyright (C) 2017-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/charconv.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{charconv}
*/
#ifndef _GLIBCXX_CHARCONV_H
#define _GLIBCXX_CHARCONV_H 1
#pragma GCC system_header
#if __cplusplus >= 201103L
#include <type_traits>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace __detail
{
// Generic implementation for arbitrary bases.
template<typename _Tp>
_GLIBCXX14_CONSTEXPR unsigned
__to_chars_len(_Tp __value, int __base = 10) noexcept
{
static_assert(is_integral<_Tp>::value, "implementation bug");
static_assert(is_unsigned<_Tp>::value, "implementation bug");
unsigned __n = 1;
const unsigned __b2 = __base * __base;
const unsigned __b3 = __b2 * __base;
const unsigned long __b4 = __b3 * __base;
for (;;)
{
if (__value < (unsigned)__base) return __n;
if (__value < __b2) return __n + 1;
if (__value < __b3) return __n + 2;
if (__value < __b4) return __n + 3;
__value /= __b4;
__n += 4;
}
}
// Write an unsigned integer value to the range [first,first+len).
// The caller is required to provide a buffer of exactly the right size
// (which can be determined by the __to_chars_len function).
template<typename _Tp>
void
__to_chars_10_impl(char* __first, unsigned __len, _Tp __val) noexcept
{
static_assert(is_integral<_Tp>::value, "implementation bug");
static_assert(is_unsigned<_Tp>::value, "implementation bug");
static constexpr char __digits[201] =
"0001020304050607080910111213141516171819"
"2021222324252627282930313233343536373839"
"4041424344454647484950515253545556575859"
"6061626364656667686970717273747576777879"
"8081828384858687888990919293949596979899";
unsigned __pos = __len - 1;
while (__val >= 100)
{
auto const __num = (__val % 100) * 2;
__val /= 100;
__first[__pos] = __digits[__num + 1];
__first[__pos - 1] = __digits[__num];
__pos -= 2;
}
if (__val >= 10)
{
auto const __num = __val * 2;
__first[1] = __digits[__num + 1];
__first[0] = __digits[__num];
}
else
__first[0] = '0' + __val;
}
} // namespace __detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++11
#endif // _GLIBCXX_CHARCONV_H

View File

@ -0,0 +1,840 @@
// Locale support (codecvt) -*- C++ -*-
// Copyright (C) 2000-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/codecvt.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{locale}
*/
//
// ISO C++ 14882: 22.2.1.5 Template class codecvt
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
#ifndef _CODECVT_H
#define _CODECVT_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/// Empty base class for codecvt facet [22.2.1.5].
class codecvt_base
{
public:
enum result
{
ok,
partial,
error,
noconv
};
};
/**
* @brief Common base for codecvt functions.
*
* This template class provides implementations of the public functions
* that forward to the protected virtual functions.
*
* This template also provides abstract stubs for the protected virtual
* functions.
*/
template<typename _InternT, typename _ExternT, typename _StateT>
class __codecvt_abstract_base
: public locale::facet, public codecvt_base
{
public:
// Types:
typedef codecvt_base::result result;
typedef _InternT intern_type;
typedef _ExternT extern_type;
typedef _StateT state_type;
// 22.2.1.5.1 codecvt members
/**
* @brief Convert from internal to external character set.
*
* Converts input string of intern_type to output string of
* extern_type. This is analogous to wcsrtombs. It does this by
* calling codecvt::do_out.
*
* The source and destination character sets are determined by the
* facet's locale, internal and external types.
*
* The characters in [from,from_end) are converted and written to
* [to,to_end). from_next and to_next are set to point to the
* character following the last successfully converted character,
* respectively. If the result needed no conversion, from_next and
* to_next are not affected.
*
* The @a state argument should be initialized if the input is at the
* beginning and carried from a previous call if continuing
* conversion. There are no guarantees about how @a state is used.
*
* The result returned is a member of codecvt_base::result. If
* all the input is converted, returns codecvt_base::ok. If no
* conversion is necessary, returns codecvt_base::noconv. If
* the input ends early or there is insufficient space in the
* output, returns codecvt_base::partial. Otherwise the
* conversion failed and codecvt_base::error is returned.
*
* @param __state Persistent conversion state data.
* @param __from Start of input.
* @param __from_end End of input.
* @param __from_next Returns start of unconverted data.
* @param __to Start of output buffer.
* @param __to_end End of output buffer.
* @param __to_next Returns start of unused output area.
* @return codecvt_base::result.
*/
result
out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const
{
return this->do_out(__state, __from, __from_end, __from_next,
__to, __to_end, __to_next);
}
/**
* @brief Reset conversion state.
*
* Writes characters to output that would restore @a state to initial
* conditions. The idea is that if a partial conversion occurs, then
* the converting the characters written by this function would leave
* the state in initial conditions, rather than partial conversion
* state. It does this by calling codecvt::do_unshift().
*
* For example, if 4 external characters always converted to 1 internal
* character, and input to in() had 6 external characters with state
* saved, this function would write two characters to the output and
* set the state to initialized conditions.
*
* The source and destination character sets are determined by the
* facet's locale, internal and external types.
*
* The result returned is a member of codecvt_base::result. If the
* state could be reset and data written, returns codecvt_base::ok. If
* no conversion is necessary, returns codecvt_base::noconv. If the
* output has insufficient space, returns codecvt_base::partial.
* Otherwise the reset failed and codecvt_base::error is returned.
*
* @param __state Persistent conversion state data.
* @param __to Start of output buffer.
* @param __to_end End of output buffer.
* @param __to_next Returns start of unused output area.
* @return codecvt_base::result.
*/
result
unshift(state_type& __state, extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const
{ return this->do_unshift(__state, __to,__to_end,__to_next); }
/**
* @brief Convert from external to internal character set.
*
* Converts input string of extern_type to output string of
* intern_type. This is analogous to mbsrtowcs. It does this by
* calling codecvt::do_in.
*
* The source and destination character sets are determined by the
* facet's locale, internal and external types.
*
* The characters in [from,from_end) are converted and written to
* [to,to_end). from_next and to_next are set to point to the
* character following the last successfully converted character,
* respectively. If the result needed no conversion, from_next and
* to_next are not affected.
*
* The @a state argument should be initialized if the input is at the
* beginning and carried from a previous call if continuing
* conversion. There are no guarantees about how @a state is used.
*
* The result returned is a member of codecvt_base::result. If
* all the input is converted, returns codecvt_base::ok. If no
* conversion is necessary, returns codecvt_base::noconv. If
* the input ends early or there is insufficient space in the
* output, returns codecvt_base::partial. Otherwise the
* conversion failed and codecvt_base::error is returned.
*
* @param __state Persistent conversion state data.
* @param __from Start of input.
* @param __from_end End of input.
* @param __from_next Returns start of unconverted data.
* @param __to Start of output buffer.
* @param __to_end End of output buffer.
* @param __to_next Returns start of unused output area.
* @return codecvt_base::result.
*/
result
in(state_type& __state, const extern_type* __from,
const extern_type* __from_end, const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const
{
return this->do_in(__state, __from, __from_end, __from_next,
__to, __to_end, __to_next);
}
int
encoding() const throw()
{ return this->do_encoding(); }
bool
always_noconv() const throw()
{ return this->do_always_noconv(); }
int
length(state_type& __state, const extern_type* __from,
const extern_type* __end, size_t __max) const
{ return this->do_length(__state, __from, __end, __max); }
int
max_length() const throw()
{ return this->do_max_length(); }
protected:
explicit
__codecvt_abstract_base(size_t __refs = 0) : locale::facet(__refs) { }
virtual
~__codecvt_abstract_base() { }
/**
* @brief Convert from internal to external character set.
*
* Converts input string of intern_type to output string of
* extern_type. This function is a hook for derived classes to change
* the value returned. @see out for more information.
*/
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const = 0;
virtual result
do_unshift(state_type& __state, extern_type* __to,
extern_type* __to_end, extern_type*& __to_next) const = 0;
virtual result
do_in(state_type& __state, const extern_type* __from,
const extern_type* __from_end, const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const = 0;
virtual int
do_encoding() const throw() = 0;
virtual bool
do_always_noconv() const throw() = 0;
virtual int
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const = 0;
virtual int
do_max_length() const throw() = 0;
};
/**
* @brief Primary class template codecvt.
* @ingroup locales
*
* NB: Generic, mostly useless implementation.
*
*/
template<typename _InternT, typename _ExternT, typename _StateT>
class codecvt
: public __codecvt_abstract_base<_InternT, _ExternT, _StateT>
{
public:
// Types:
typedef codecvt_base::result result;
typedef _InternT intern_type;
typedef _ExternT extern_type;
typedef _StateT state_type;
protected:
__c_locale _M_c_locale_codecvt;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0)
: __codecvt_abstract_base<_InternT, _ExternT, _StateT> (__refs),
_M_c_locale_codecvt(0)
{ }
explicit
codecvt(__c_locale __cloc, size_t __refs = 0);
protected:
virtual
~codecvt() { }
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state, extern_type* __to,
extern_type* __to_end, extern_type*& __to_next) const;
virtual result
do_in(state_type& __state, const extern_type* __from,
const extern_type* __from_end, const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual int
do_encoding() const throw();
virtual bool
do_always_noconv() const throw();
virtual int
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
template<typename _InternT, typename _ExternT, typename _StateT>
locale::id codecvt<_InternT, _ExternT, _StateT>::id;
/// class codecvt<char, char, mbstate_t> specialization.
template<>
class codecvt<char, char, mbstate_t>
: public __codecvt_abstract_base<char, char, mbstate_t>
{
friend class messages<char>;
public:
// Types:
typedef char intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
protected:
__c_locale _M_c_locale_codecvt;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0);
explicit
codecvt(__c_locale __cloc, size_t __refs = 0);
protected:
virtual
~codecvt();
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state, extern_type* __to,
extern_type* __to_end, extern_type*& __to_next) const;
virtual result
do_in(state_type& __state, const extern_type* __from,
const extern_type* __from_end, const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual int
do_encoding() const throw();
virtual bool
do_always_noconv() const throw();
virtual int
do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
#ifdef _GLIBCXX_USE_WCHAR_T
/** @brief Class codecvt<wchar_t, char, mbstate_t> specialization.
*
* Converts between narrow and wide characters in the native character set
*/
template<>
class codecvt<wchar_t, char, mbstate_t>
: public __codecvt_abstract_base<wchar_t, char, mbstate_t>
{
friend class messages<wchar_t>;
public:
// Types:
typedef wchar_t intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
protected:
__c_locale _M_c_locale_codecvt;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0);
explicit
codecvt(__c_locale __cloc, size_t __refs = 0);
protected:
virtual
~codecvt();
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_in(state_type& __state,
const extern_type* __from, const extern_type* __from_end,
const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual
int do_encoding() const throw();
virtual
bool do_always_noconv() const throw();
virtual
int do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
#endif //_GLIBCXX_USE_WCHAR_T
#if __cplusplus >= 201103L
/** @brief Class codecvt<char16_t, char, mbstate_t> specialization.
*
* Converts between UTF-16 and UTF-8.
*/
template<>
class codecvt<char16_t, char, mbstate_t>
: public __codecvt_abstract_base<char16_t, char, mbstate_t>
{
public:
// Types:
typedef char16_t intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0)
: __codecvt_abstract_base<char16_t, char, mbstate_t>(__refs) { }
protected:
virtual
~codecvt();
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_in(state_type& __state,
const extern_type* __from, const extern_type* __from_end,
const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual
int do_encoding() const throw();
virtual
bool do_always_noconv() const throw();
virtual
int do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
/** @brief Class codecvt<char32_t, char, mbstate_t> specialization.
*
* Converts between UTF-32 and UTF-8.
*/
template<>
class codecvt<char32_t, char, mbstate_t>
: public __codecvt_abstract_base<char32_t, char, mbstate_t>
{
public:
// Types:
typedef char32_t intern_type;
typedef char extern_type;
typedef mbstate_t state_type;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0)
: __codecvt_abstract_base<char32_t, char, mbstate_t>(__refs) { }
protected:
virtual
~codecvt();
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_in(state_type& __state,
const extern_type* __from, const extern_type* __from_end,
const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual
int do_encoding() const throw();
virtual
bool do_always_noconv() const throw();
virtual
int do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
#ifdef _GLIBCXX_USE_CHAR8_T
/** @brief Class codecvt<char16_t, char8_t, mbstate_t> specialization.
*
* Converts between UTF-16 and UTF-8.
*/
template<>
class codecvt<char16_t, char8_t, mbstate_t>
: public __codecvt_abstract_base<char16_t, char8_t, mbstate_t>
{
public:
// Types:
typedef char16_t intern_type;
typedef char8_t extern_type;
typedef mbstate_t state_type;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0)
: __codecvt_abstract_base<char16_t, char8_t, mbstate_t>(__refs) { }
protected:
virtual
~codecvt();
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_in(state_type& __state,
const extern_type* __from, const extern_type* __from_end,
const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual
int do_encoding() const throw();
virtual
bool do_always_noconv() const throw();
virtual
int do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
/** @brief Class codecvt<char32_t, char8_t, mbstate_t> specialization.
*
* Converts between UTF-32 and UTF-8.
*/
template<>
class codecvt<char32_t, char8_t, mbstate_t>
: public __codecvt_abstract_base<char32_t, char8_t, mbstate_t>
{
public:
// Types:
typedef char32_t intern_type;
typedef char8_t extern_type;
typedef mbstate_t state_type;
public:
static locale::id id;
explicit
codecvt(size_t __refs = 0)
: __codecvt_abstract_base<char32_t, char8_t, mbstate_t>(__refs) { }
protected:
virtual
~codecvt();
virtual result
do_out(state_type& __state, const intern_type* __from,
const intern_type* __from_end, const intern_type*& __from_next,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_unshift(state_type& __state,
extern_type* __to, extern_type* __to_end,
extern_type*& __to_next) const;
virtual result
do_in(state_type& __state,
const extern_type* __from, const extern_type* __from_end,
const extern_type*& __from_next,
intern_type* __to, intern_type* __to_end,
intern_type*& __to_next) const;
virtual
int do_encoding() const throw();
virtual
bool do_always_noconv() const throw();
virtual
int do_length(state_type&, const extern_type* __from,
const extern_type* __end, size_t __max) const;
virtual int
do_max_length() const throw();
};
#endif // _GLIBCXX_USE_CHAR8_T
#endif // C++11
/// class codecvt_byname [22.2.1.6].
template<typename _InternT, typename _ExternT, typename _StateT>
class codecvt_byname : public codecvt<_InternT, _ExternT, _StateT>
{
public:
explicit
codecvt_byname(const char* __s, size_t __refs = 0)
: codecvt<_InternT, _ExternT, _StateT>(__refs)
{
if (__builtin_strcmp(__s, "C") != 0
&& __builtin_strcmp(__s, "POSIX") != 0)
{
this->_S_destroy_c_locale(this->_M_c_locale_codecvt);
this->_S_create_c_locale(this->_M_c_locale_codecvt, __s);
}
}
#if __cplusplus >= 201103L
explicit
codecvt_byname(const string& __s, size_t __refs = 0)
: codecvt_byname(__s.c_str(), __refs) { }
#endif
protected:
virtual
~codecvt_byname() { }
};
#if __cplusplus >= 201103L
template<>
class codecvt_byname<char16_t, char, mbstate_t>
: public codecvt<char16_t, char, mbstate_t>
{
public:
explicit
codecvt_byname(const char*, size_t __refs = 0)
: codecvt<char16_t, char, mbstate_t>(__refs) { }
explicit
codecvt_byname(const string& __s, size_t __refs = 0)
: codecvt_byname(__s.c_str(), __refs) { }
protected:
virtual
~codecvt_byname() { }
};
template<>
class codecvt_byname<char32_t, char, mbstate_t>
: public codecvt<char32_t, char, mbstate_t>
{
public:
explicit
codecvt_byname(const char*, size_t __refs = 0)
: codecvt<char32_t, char, mbstate_t>(__refs) { }
explicit
codecvt_byname(const string& __s, size_t __refs = 0)
: codecvt_byname(__s.c_str(), __refs) { }
protected:
virtual
~codecvt_byname() { }
};
#if defined(_GLIBCXX_USE_CHAR8_T)
template<>
class codecvt_byname<char16_t, char8_t, mbstate_t>
: public codecvt<char16_t, char8_t, mbstate_t>
{
public:
explicit
codecvt_byname(const char* __s, size_t __refs = 0)
: codecvt<char16_t, char8_t, mbstate_t>(__refs) { }
explicit
codecvt_byname(const string& __s, size_t __refs = 0)
: codecvt_byname(__s.c_str(), __refs) { }
protected:
virtual
~codecvt_byname() { }
};
template<>
class codecvt_byname<char32_t, char8_t, mbstate_t>
: public codecvt<char32_t, char8_t, mbstate_t>
{
public:
explicit
codecvt_byname(const char* __s, size_t __refs = 0)
: codecvt<char32_t, char8_t, mbstate_t>(__refs) { }
explicit
codecvt_byname(const string& __s, size_t __refs = 0)
: codecvt_byname(__s.c_str(), __refs) { }
protected:
virtual
~codecvt_byname() { }
};
#endif
#endif // C++11
// Inhibit implicit instantiations for required instantiations,
// which are defined via explicit instantiations elsewhere.
#if _GLIBCXX_EXTERN_TEMPLATE
extern template class codecvt_byname<char, char, mbstate_t>;
extern template
const codecvt<char, char, mbstate_t>&
use_facet<codecvt<char, char, mbstate_t> >(const locale&);
extern template
bool
has_facet<codecvt<char, char, mbstate_t> >(const locale&);
#ifdef _GLIBCXX_USE_WCHAR_T
extern template class codecvt_byname<wchar_t, char, mbstate_t>;
extern template
const codecvt<wchar_t, char, mbstate_t>&
use_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
extern template
bool
has_facet<codecvt<wchar_t, char, mbstate_t> >(const locale&);
#endif
#if __cplusplus >= 201103L
extern template class codecvt_byname<char16_t, char, mbstate_t>;
extern template class codecvt_byname<char32_t, char, mbstate_t>;
#if defined(_GLIBCXX_USE_CHAR8_T)
extern template class codecvt_byname<char16_t, char8_t, mbstate_t>;
extern template class codecvt_byname<char32_t, char8_t, mbstate_t>;
#endif
#endif
#endif
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // _CODECVT_H

View File

@ -0,0 +1,81 @@
// Concept-checking control -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/concept_check.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{iterator}
*/
#ifndef _CONCEPT_CHECK_H
#define _CONCEPT_CHECK_H 1
#pragma GCC system_header
#include <bits/c++config.h>
// All places in libstdc++-v3 where these are used, or /might/ be used, or
// don't need to be used, or perhaps /should/ be used, are commented with
// "concept requirements" (and maybe some more text). So grep like crazy
// if you're looking for additional places to use these.
// Concept-checking code is off by default unless users turn it on via
// configure options or editing c++config.h.
// It is not supported for freestanding implementations.
#if !defined(_GLIBCXX_CONCEPT_CHECKS) || !_GLIBCXX_HOSTED
#define __glibcxx_function_requires(...)
#define __glibcxx_class_requires(_a,_b)
#define __glibcxx_class_requires2(_a,_b,_c)
#define __glibcxx_class_requires3(_a,_b,_c,_d)
#define __glibcxx_class_requires4(_a,_b,_c,_d,_e)
#else // the checks are on
#include <bits/boost_concept_check.h>
// Note that the obvious and elegant approach of
//
//#define glibcxx_function_requires(C) debug::function_requires< debug::C >()
//
// won't work due to concept templates with more than one parameter, e.g.,
// BinaryPredicateConcept. The preprocessor tries to split things up on
// the commas in the template argument list. We can't use an inner pair of
// parenthesis to hide the commas, because "debug::(Temp<Foo,Bar>)" isn't
// a valid instantiation pattern. Thus, we steal a feature from C99.
#define __glibcxx_function_requires(...) \
__gnu_cxx::__function_requires< __gnu_cxx::__VA_ARGS__ >();
#define __glibcxx_class_requires(_a,_C) \
_GLIBCXX_CLASS_REQUIRES(_a, __gnu_cxx, _C);
#define __glibcxx_class_requires2(_a,_b,_C) \
_GLIBCXX_CLASS_REQUIRES2(_a, _b, __gnu_cxx, _C);
#define __glibcxx_class_requires3(_a,_b,_c,_C) \
_GLIBCXX_CLASS_REQUIRES3(_a, _b, _c, __gnu_cxx, _C);
#define __glibcxx_class_requires4(_a,_b,_c,_d,_C) \
_GLIBCXX_CLASS_REQUIRES4(_a, _b, _c, _d, __gnu_cxx, _C);
#endif // enable/disable
#endif // _GLIBCXX_CONCEPT_CHECK

View File

@ -0,0 +1,551 @@
// The -*- C++ -*- type traits classes for internal use in libstdc++
// Copyright (C) 2000-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cpp_type_traits.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{ext/type_traits}
*/
// Written by Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
#ifndef _CPP_TYPE_TRAITS_H
#define _CPP_TYPE_TRAITS_H 1
#pragma GCC system_header
#include <bits/c++config.h>
//
// This file provides some compile-time information about various types.
// These representations were designed, on purpose, to be constant-expressions
// and not types as found in <bits/type_traits.h>. In particular, they
// can be used in control structures and the optimizer hopefully will do
// the obvious thing.
//
// Why integral expressions, and not functions nor types?
// Firstly, these compile-time entities are used as template-arguments
// so function return values won't work: We need compile-time entities.
// We're left with types and constant integral expressions.
// Secondly, from the point of view of ease of use, type-based compile-time
// information is -not- *that* convenient. One has to write lots of
// overloaded functions and to hope that the compiler will select the right
// one. As a net effect, the overall structure isn't very clear at first
// glance.
// Thirdly, partial ordering and overload resolution (of function templates)
// is highly costly in terms of compiler-resource. It is a Good Thing to
// keep these resource consumption as least as possible.
//
// See valarray_array.h for a case use.
//
// -- Gaby (dosreis@cmla.ens-cachan.fr) 2000-03-06.
//
// Update 2005: types are also provided and <bits/type_traits.h> has been
// removed.
//
extern "C++" {
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
struct __true_type { };
struct __false_type { };
template<bool>
struct __truth_type
{ typedef __false_type __type; };
template<>
struct __truth_type<true>
{ typedef __true_type __type; };
// N.B. The conversions to bool are needed due to the issue
// explained in c++/19404.
template<class _Sp, class _Tp>
struct __traitor
{
enum { __value = bool(_Sp::__value) || bool(_Tp::__value) };
typedef typename __truth_type<__value>::__type __type;
};
// Compare for equality of types.
template<typename, typename>
struct __are_same
{
enum { __value = 0 };
typedef __false_type __type;
};
template<typename _Tp>
struct __are_same<_Tp, _Tp>
{
enum { __value = 1 };
typedef __true_type __type;
};
// Holds if the template-argument is a void type.
template<typename _Tp>
struct __is_void
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_void<void>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// Integer types
//
template<typename _Tp>
struct __is_integer
{
enum { __value = 0 };
typedef __false_type __type;
};
// Thirteen specializations (yes there are eleven standard integer
// types; <em>long long</em> and <em>unsigned long long</em> are
// supported as extensions). Up to four target-specific __int<N>
// types are supported as well.
template<>
struct __is_integer<bool>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<signed char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned char>
{
enum { __value = 1 };
typedef __true_type __type;
};
# ifdef _GLIBCXX_USE_WCHAR_T
template<>
struct __is_integer<wchar_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
# endif
#ifdef _GLIBCXX_USE_CHAR8_T
template<>
struct __is_integer<char8_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
#if __cplusplus >= 201103L
template<>
struct __is_integer<char16_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<char32_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<>
struct __is_integer<short>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned short>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<int>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned int>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<long long>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_integer<unsigned long long>
{
enum { __value = 1 };
typedef __true_type __type;
};
#define __INT_N(TYPE) \
template<> \
struct __is_integer<TYPE> \
{ \
enum { __value = 1 }; \
typedef __true_type __type; \
}; \
template<> \
struct __is_integer<unsigned TYPE> \
{ \
enum { __value = 1 }; \
typedef __true_type __type; \
};
#ifdef __GLIBCXX_TYPE_INT_N_0
__INT_N(__GLIBCXX_TYPE_INT_N_0)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_1
__INT_N(__GLIBCXX_TYPE_INT_N_1)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_2
__INT_N(__GLIBCXX_TYPE_INT_N_2)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_3
__INT_N(__GLIBCXX_TYPE_INT_N_3)
#endif
#undef __INT_N
//
// Floating point types
//
template<typename _Tp>
struct __is_floating
{
enum { __value = 0 };
typedef __false_type __type;
};
// three specializations (float, double and 'long double')
template<>
struct __is_floating<float>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_floating<double>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_floating<long double>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// Pointer types
//
template<typename _Tp>
struct __is_pointer
{
enum { __value = 0 };
typedef __false_type __type;
};
template<typename _Tp>
struct __is_pointer<_Tp*>
{
enum { __value = 1 };
typedef __true_type __type;
};
//
// An arithmetic type is an integer type or a floating point type
//
template<typename _Tp>
struct __is_arithmetic
: public __traitor<__is_integer<_Tp>, __is_floating<_Tp> >
{ };
//
// A scalar type is an arithmetic type or a pointer type
//
template<typename _Tp>
struct __is_scalar
: public __traitor<__is_arithmetic<_Tp>, __is_pointer<_Tp> >
{ };
//
// For use in std::copy and std::find overloads for streambuf iterators.
//
template<typename _Tp>
struct __is_char
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_char<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
#ifdef _GLIBCXX_USE_WCHAR_T
template<>
struct __is_char<wchar_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<typename _Tp>
struct __is_byte
{
enum { __value = 0 };
typedef __false_type __type;
};
template<>
struct __is_byte<char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_byte<signed char>
{
enum { __value = 1 };
typedef __true_type __type;
};
template<>
struct __is_byte<unsigned char>
{
enum { __value = 1 };
typedef __true_type __type;
};
#if __cplusplus >= 201703L
enum class byte : unsigned char;
template<>
struct __is_byte<byte>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif // C++17
#ifdef _GLIBCXX_USE_CHAR8_T
template<>
struct __is_byte<char8_t>
{
enum { __value = 1 };
typedef __true_type __type;
};
#endif
template<typename> struct iterator_traits;
// A type that is safe for use with memcpy, memmove, memcmp etc.
template<typename _Tp>
struct __is_nonvolatile_trivially_copyable
{
enum { __value = __is_trivially_copyable(_Tp) };
};
// Cannot use memcpy/memmove/memcmp on volatile types even if they are
// trivially copyable, so ensure __memcpyable<volatile int*, volatile int*>
// and similar will be false.
template<typename _Tp>
struct __is_nonvolatile_trivially_copyable<volatile _Tp>
{
enum { __value = 0 };
};
// Whether two iterator types can be used with memcpy/memmove.
template<typename _OutputIter, typename _InputIter>
struct __memcpyable
{
enum { __value = 0 };
};
template<typename _Tp>
struct __memcpyable<_Tp*, _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
template<typename _Tp>
struct __memcpyable<_Tp*, const _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
// Whether two iterator types can be used with memcmp.
// This trait only says it's well-formed to use memcmp, not that it
// gives the right answer for a given algorithm. So for example, std::equal
// needs to add additional checks that the types are integers or pointers,
// because other trivially copyable types can overload operator==.
template<typename _Iter1, typename _Iter2>
struct __memcmpable
{
enum { __value = 0 };
};
// OK to use memcmp with pointers to trivially copyable types.
template<typename _Tp>
struct __memcmpable<_Tp*, _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
template<typename _Tp>
struct __memcmpable<const _Tp*, _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
template<typename _Tp>
struct __memcmpable<_Tp*, const _Tp*>
: __is_nonvolatile_trivially_copyable<_Tp>
{ };
// Whether memcmp can be used to determine ordering for a type
// e.g. in std::lexicographical_compare or three-way comparisons.
// True for unsigned narrow character types (and std::byte).
template<typename _Tp, bool _TreatAsBytes = __is_byte<_Tp>::__value>
struct __is_memcmp_ordered
{
static const bool __value = _Tp(-1) > _Tp(1); // is unsigned
};
template<typename _Tp>
struct __is_memcmp_ordered<_Tp, false>
{
static const bool __value = false;
};
// Whether two types can be compared using memcmp.
template<typename _Tp, typename _Up, bool = sizeof(_Tp) == sizeof(_Up)>
struct __is_memcmp_ordered_with
{
static const bool __value = __is_memcmp_ordered<_Tp>::__value
&& __is_memcmp_ordered<_Up>::__value;
};
template<typename _Tp, typename _Up>
struct __is_memcmp_ordered_with<_Tp, _Up, false>
{
static const bool __value = false;
};
#if __cplusplus >= 201703L
// std::byte can only be compared to itself, not to other types.
template<>
struct __is_memcmp_ordered_with<std::byte, std::byte, true>
{ static constexpr bool __value = true; };
template<typename _Tp, bool _SameSize>
struct __is_memcmp_ordered_with<_Tp, std::byte, _SameSize>
{ static constexpr bool __value = false; };
template<typename _Up, bool _SameSize>
struct __is_memcmp_ordered_with<std::byte, _Up, _SameSize>
{ static constexpr bool __value = false; };
#endif
//
// Move iterator type
//
template<typename _Tp>
struct __is_move_iterator
{
enum { __value = 0 };
typedef __false_type __type;
};
// Fallback implementation of the function in bits/stl_iterator.h used to
// remove the move_iterator wrapper.
template<typename _Iterator>
_GLIBCXX20_CONSTEXPR
inline _Iterator
__miter_base(_Iterator __it)
{ return __it; }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
} // extern "C++"
#endif //_CPP_TYPE_TRAITS_H

View File

@ -0,0 +1,60 @@
// cxxabi.h subset for cancellation -*- C++ -*-
// Copyright (C) 2007-2020 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_forced.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{cxxabi.h}
*/
#ifndef _CXXABI_FORCED_H
#define _CXXABI_FORCED_H 1
#pragma GCC system_header
#pragma GCC visibility push(default)
#ifdef __cplusplus
namespace __cxxabiv1
{
/**
* @brief Thrown as part of forced unwinding.
* @ingroup exceptions
*
* A magic placeholder class that can be caught by reference to
* recognize forced unwinding.
*/
class __forced_unwind
{
virtual ~__forced_unwind() throw();
// Prevent catch by value.
virtual void __pure_dummy() = 0;
};
}
#endif // __cplusplus
#pragma GCC visibility pop
#endif // __CXXABI_FORCED_H

View File

@ -0,0 +1,80 @@
// ABI Support -*- C++ -*-
// Copyright (C) 2016-2020 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/cxxabi_init_exception.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
*/
#ifndef _CXXABI_INIT_EXCEPTION_H
#define _CXXABI_INIT_EXCEPTION_H 1
#pragma GCC system_header
#pragma GCC visibility push(default)
#include <stddef.h>
#include <bits/c++config.h>
#ifndef _GLIBCXX_CDTOR_CALLABI
#define _GLIBCXX_CDTOR_CALLABI
#define _GLIBCXX_HAVE_CDTOR_CALLABI 0
#else
#define _GLIBCXX_HAVE_CDTOR_CALLABI 1
#endif
#ifdef __cplusplus
namespace std
{
class type_info;
}
namespace __cxxabiv1
{
struct __cxa_refcounted_exception;
extern "C"
{
// Allocate memory for the primary exception plus the thrown object.
void*
__cxa_allocate_exception(size_t) _GLIBCXX_NOTHROW;
void
__cxa_free_exception(void*) _GLIBCXX_NOTHROW;
// Initialize exception (this is a GNU extension)
__cxa_refcounted_exception*
__cxa_init_primary_exception(void *object, std::type_info *tinfo,
void (_GLIBCXX_CDTOR_CALLABI *dest) (void *)) _GLIBCXX_NOTHROW;
}
} // namespace __cxxabiv1
#endif
#pragma GCC visibility pop
#endif // _CXXABI_INIT_EXCEPTION_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,312 @@
// <bits/enable_special_members.h> -*- C++ -*-
// Copyright (C) 2013-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/enable_special_members.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
*/
#ifndef _ENABLE_SPECIAL_MEMBERS_H
#define _ENABLE_SPECIAL_MEMBERS_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
struct _Enable_default_constructor_tag
{
explicit constexpr _Enable_default_constructor_tag() = default;
};
/**
* @brief A mixin helper to conditionally enable or disable the default
* constructor.
* @sa _Enable_special_members
*/
template<bool _Switch, typename _Tag = void>
struct _Enable_default_constructor
{
constexpr _Enable_default_constructor() noexcept = default;
constexpr _Enable_default_constructor(_Enable_default_constructor const&)
noexcept = default;
constexpr _Enable_default_constructor(_Enable_default_constructor&&)
noexcept = default;
_Enable_default_constructor&
operator=(_Enable_default_constructor const&) noexcept = default;
_Enable_default_constructor&
operator=(_Enable_default_constructor&&) noexcept = default;
// Can be used in other ctors.
constexpr explicit
_Enable_default_constructor(_Enable_default_constructor_tag) { }
};
/**
* @brief A mixin helper to conditionally enable or disable the default
* destructor.
* @sa _Enable_special_members
*/
template<bool _Switch, typename _Tag = void>
struct _Enable_destructor { };
/**
* @brief A mixin helper to conditionally enable or disable the copy/move
* special members.
* @sa _Enable_special_members
*/
template<bool _Copy, bool _CopyAssignment,
bool _Move, bool _MoveAssignment,
typename _Tag = void>
struct _Enable_copy_move { };
/**
* @brief A mixin helper to conditionally enable or disable the special
* members.
*
* The @c _Tag type parameter is to make mixin bases unique and thus avoid
* ambiguities.
*/
template<bool _Default, bool _Destructor,
bool _Copy, bool _CopyAssignment,
bool _Move, bool _MoveAssignment,
typename _Tag = void>
struct _Enable_special_members
: private _Enable_default_constructor<_Default, _Tag>,
private _Enable_destructor<_Destructor, _Tag>,
private _Enable_copy_move<_Copy, _CopyAssignment,
_Move, _MoveAssignment,
_Tag>
{ };
// Boilerplate follows.
template<typename _Tag>
struct _Enable_default_constructor<false, _Tag>
{
constexpr _Enable_default_constructor() noexcept = delete;
constexpr _Enable_default_constructor(_Enable_default_constructor const&)
noexcept = default;
constexpr _Enable_default_constructor(_Enable_default_constructor&&)
noexcept = default;
_Enable_default_constructor&
operator=(_Enable_default_constructor const&) noexcept = default;
_Enable_default_constructor&
operator=(_Enable_default_constructor&&) noexcept = default;
// Can be used in other ctors.
constexpr explicit
_Enable_default_constructor(_Enable_default_constructor_tag) { }
};
template<typename _Tag>
struct _Enable_destructor<false, _Tag>
{ ~_Enable_destructor() noexcept = delete; };
template<typename _Tag>
struct _Enable_copy_move<false, true, true, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<true, false, true, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<false, false, true, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<true, true, false, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<false, true, false, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<true, false, false, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<false, false, false, true, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = default;
};
template<typename _Tag>
struct _Enable_copy_move<true, true, true, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<false, true, true, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<true, false, true, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<false, false, true, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<true, true, false, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<false, true, false, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = default;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<true, false, false, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
template<typename _Tag>
struct _Enable_copy_move<false, false, false, false, _Tag>
{
constexpr _Enable_copy_move() noexcept = default;
constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept = delete;
constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move const&) noexcept = delete;
_Enable_copy_move&
operator=(_Enable_copy_move&&) noexcept = delete;
};
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // _ENABLE_SPECIAL_MEMBERS_H

View File

@ -0,0 +1,72 @@
// <bits/erase_if.h> -*- C++ -*-
// Copyright (C) 2015-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/erase_if.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
*/
#ifndef _GLIBCXX_ERASE_IF_H
#define _GLIBCXX_ERASE_IF_H 1
#pragma GCC system_header
#if __cplusplus >= 201402L
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#if __cplusplus > 201703L
# define __cpp_lib_erase_if 202002L
#endif
namespace __detail
{
template<typename _Container, typename _Predicate>
typename _Container::size_type
__erase_nodes_if(_Container& __cont, _Predicate __pred)
{
typename _Container::size_type __num = 0;
for (auto __iter = __cont.begin(), __last = __cont.end();
__iter != __last;)
{
if (__pred(*__iter))
{
__iter = __cont.erase(__iter);
++__num;
}
else
++__iter;
}
return __num;
}
} // namespace __detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++14
#endif // _GLIBCXX_ERASE_IF_H

View File

@ -0,0 +1,86 @@
// Exception Handling support header for -*- C++ -*-
// Copyright (C) 2016-2020 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/exception.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly.
*/
#ifndef __EXCEPTION_H
#define __EXCEPTION_H 1
#pragma GCC system_header
#pragma GCC visibility push(default)
#include <bits/c++config.h>
extern "C++" {
namespace std
{
/**
* @defgroup exceptions Exceptions
* @ingroup diagnostics
*
* Classes and functions for reporting errors via exceptions.
* @{
*/
/**
* @brief Base class for all library exceptions.
*
* This is the base class for all exceptions thrown by the standard
* library, and by certain language expressions. You are free to derive
* your own %exception classes, or use a different hierarchy, or to
* throw non-class data (e.g., fundamental types).
*/
class exception
{
public:
exception() _GLIBCXX_NOTHROW { }
virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
#if __cplusplus >= 201103L
exception(const exception&) = default;
exception& operator=(const exception&) = default;
exception(exception&&) = default;
exception& operator=(exception&&) = default;
#endif
/** Returns a C-style character string describing the general cause
* of the current error. */
virtual const char*
what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_NOTHROW;
};
/// @}
} // namespace std
}
#pragma GCC visibility pop
#endif

View File

@ -0,0 +1,45 @@
// -fno-exceptions Support -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/exception_defines.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*/
#ifndef _EXCEPTION_DEFINES_H
#define _EXCEPTION_DEFINES_H 1
#if ! __cpp_exceptions
// Iff -fno-exceptions, transform error handling code to work without it.
# define __try if (true)
# define __catch(X) if (false)
# define __throw_exception_again
#else
// Else proceed normally.
# define __try try
# define __catch(X) catch(X)
# define __throw_exception_again throw
#endif
#endif

View File

@ -0,0 +1,224 @@
// Exception Handling support header (exception_ptr class) for -*- C++ -*-
// Copyright (C) 2008-2020 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/exception_ptr.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*/
#ifndef _EXCEPTION_PTR_H
#define _EXCEPTION_PTR_H
#pragma GCC visibility push(default)
#include <bits/c++config.h>
#include <bits/exception_defines.h>
#include <bits/cxxabi_init_exception.h>
#include <typeinfo>
#include <new>
extern "C++" {
namespace std
{
class type_info;
/**
* @addtogroup exceptions
* @{
*/
namespace __exception_ptr
{
class exception_ptr;
}
using __exception_ptr::exception_ptr;
/** Obtain an exception_ptr to the currently handled exception. If there
* is none, or the currently handled exception is foreign, return the null
* value.
*/
exception_ptr current_exception() _GLIBCXX_USE_NOEXCEPT;
template<typename _Ex>
exception_ptr make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT;
/// Throw the object pointed to by the exception_ptr.
void rethrow_exception(exception_ptr) __attribute__ ((__noreturn__));
namespace __exception_ptr
{
using std::rethrow_exception;
/**
* @brief An opaque pointer to an arbitrary exception.
* @ingroup exceptions
*/
class exception_ptr
{
void* _M_exception_object;
explicit exception_ptr(void* __e) _GLIBCXX_USE_NOEXCEPT;
void _M_addref() _GLIBCXX_USE_NOEXCEPT;
void _M_release() _GLIBCXX_USE_NOEXCEPT;
void *_M_get() const _GLIBCXX_NOEXCEPT __attribute__ ((__pure__));
friend exception_ptr std::current_exception() _GLIBCXX_USE_NOEXCEPT;
friend void std::rethrow_exception(exception_ptr);
template<typename _Ex>
friend exception_ptr std::make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT;
public:
exception_ptr() _GLIBCXX_USE_NOEXCEPT;
exception_ptr(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
#if __cplusplus >= 201103L
exception_ptr(nullptr_t) noexcept
: _M_exception_object(0)
{ }
exception_ptr(exception_ptr&& __o) noexcept
: _M_exception_object(__o._M_exception_object)
{ __o._M_exception_object = 0; }
#endif
#if (__cplusplus < 201103L) || defined (_GLIBCXX_EH_PTR_COMPAT)
typedef void (exception_ptr::*__safe_bool)();
// For construction from nullptr or 0.
exception_ptr(__safe_bool) _GLIBCXX_USE_NOEXCEPT;
#endif
exception_ptr&
operator=(const exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
#if __cplusplus >= 201103L
exception_ptr&
operator=(exception_ptr&& __o) noexcept
{
exception_ptr(static_cast<exception_ptr&&>(__o)).swap(*this);
return *this;
}
#endif
~exception_ptr() _GLIBCXX_USE_NOEXCEPT;
void
swap(exception_ptr&) _GLIBCXX_USE_NOEXCEPT;
#ifdef _GLIBCXX_EH_PTR_COMPAT
// Retained for compatibility with CXXABI_1.3.
void _M_safe_bool_dummy() _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__const__));
bool operator!() const _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__pure__));
operator __safe_bool() const _GLIBCXX_USE_NOEXCEPT;
#endif
#if __cplusplus >= 201103L
explicit operator bool() const
{ return _M_exception_object; }
#endif
friend bool
operator==(const exception_ptr&, const exception_ptr&)
_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
const class std::type_info*
__cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT
__attribute__ ((__pure__));
};
/// @relates exception_ptr @{
bool
operator==(const exception_ptr&, const exception_ptr&)
_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
bool
operator!=(const exception_ptr&, const exception_ptr&)
_GLIBCXX_USE_NOEXCEPT __attribute__ ((__pure__));
inline void
swap(exception_ptr& __lhs, exception_ptr& __rhs)
{ __lhs.swap(__rhs); }
// @}
/// @cond undocumented
template<typename _Ex>
inline void
__dest_thunk(void* __x)
{ static_cast<_Ex*>(__x)->~_Ex(); }
/// @endcond
} // namespace __exception_ptr
/// Obtain an exception_ptr pointing to a copy of the supplied object.
template<typename _Ex>
exception_ptr
make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
{
#if __cpp_exceptions && __cpp_rtti && !_GLIBCXX_HAVE_CDTOR_CALLABI
void* __e = __cxxabiv1::__cxa_allocate_exception(sizeof(_Ex));
(void) __cxxabiv1::__cxa_init_primary_exception(
__e, const_cast<std::type_info*>(&typeid(__ex)),
__exception_ptr::__dest_thunk<_Ex>);
try
{
::new (__e) _Ex(__ex);
return exception_ptr(__e);
}
catch(...)
{
__cxxabiv1::__cxa_free_exception(__e);
return current_exception();
}
#elif __cpp_exceptions
try
{
throw __ex;
}
catch(...)
{
return current_exception();
}
#else // no RTTI and no exceptions
return exception_ptr();
#endif
}
/// @} group exceptions
} // namespace std
} // extern "C++"
#pragma GCC visibility pop
#endif

View File

@ -0,0 +1,517 @@
// <forward_list.tcc> -*- C++ -*-
// Copyright (C) 2008-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/forward_list.tcc
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{forward_list}
*/
#ifndef _FORWARD_LIST_TCC
#define _FORWARD_LIST_TCC 1
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
template<typename _Tp, typename _Alloc>
_Fwd_list_base<_Tp, _Alloc>::
_Fwd_list_base(_Fwd_list_base&& __lst, _Node_alloc_type&& __a)
: _M_impl(std::move(__a))
{
if (__lst._M_get_Node_allocator() == _M_get_Node_allocator())
this->_M_impl._M_head = std::move(__lst._M_impl._M_head);
}
template<typename _Tp, typename _Alloc>
template<typename... _Args>
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
_M_insert_after(const_iterator __pos, _Args&&... __args)
{
_Fwd_list_node_base* __to
= const_cast<_Fwd_list_node_base*>(__pos._M_node);
_Node* __thing = _M_create_node(std::forward<_Args>(__args)...);
__thing->_M_next = __to->_M_next;
__to->_M_next = __thing;
return __to->_M_next;
}
template<typename _Tp, typename _Alloc>
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
_M_erase_after(_Fwd_list_node_base* __pos)
{
_Node* __curr = static_cast<_Node*>(__pos->_M_next);
__pos->_M_next = __curr->_M_next;
_Node_alloc_traits::destroy(_M_get_Node_allocator(),
__curr->_M_valptr());
__curr->~_Node();
_M_put_node(__curr);
return __pos->_M_next;
}
template<typename _Tp, typename _Alloc>
_Fwd_list_node_base*
_Fwd_list_base<_Tp, _Alloc>::
_M_erase_after(_Fwd_list_node_base* __pos,
_Fwd_list_node_base* __last)
{
_Node* __curr = static_cast<_Node*>(__pos->_M_next);
while (__curr != __last)
{
_Node* __temp = __curr;
__curr = static_cast<_Node*>(__curr->_M_next);
_Node_alloc_traits::destroy(_M_get_Node_allocator(),
__temp->_M_valptr());
__temp->~_Node();
_M_put_node(__temp);
}
__pos->_M_next = __last;
return __last;
}
// Called by the range constructor to implement [23.3.4.2]/9
template<typename _Tp, typename _Alloc>
template<typename _InputIterator>
void
forward_list<_Tp, _Alloc>::
_M_range_initialize(_InputIterator __first, _InputIterator __last)
{
_Node_base* __to = &this->_M_impl._M_head;
for (; __first != __last; ++__first)
{
__to->_M_next = this->_M_create_node(*__first);
__to = __to->_M_next;
}
}
// Called by forward_list(n,v,a).
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
_M_fill_initialize(size_type __n, const value_type& __value)
{
_Node_base* __to = &this->_M_impl._M_head;
for (; __n; --__n)
{
__to->_M_next = this->_M_create_node(__value);
__to = __to->_M_next;
}
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
_M_default_initialize(size_type __n)
{
_Node_base* __to = &this->_M_impl._M_head;
for (; __n; --__n)
{
__to->_M_next = this->_M_create_node();
__to = __to->_M_next;
}
}
template<typename _Tp, typename _Alloc>
forward_list<_Tp, _Alloc>&
forward_list<_Tp, _Alloc>::
operator=(const forward_list& __list)
{
if (std::__addressof(__list) != this)
{
if (_Node_alloc_traits::_S_propagate_on_copy_assign())
{
auto& __this_alloc = this->_M_get_Node_allocator();
auto& __that_alloc = __list._M_get_Node_allocator();
if (!_Node_alloc_traits::_S_always_equal()
&& __this_alloc != __that_alloc)
{
// replacement allocator cannot free existing storage
clear();
}
std::__alloc_on_copy(__this_alloc, __that_alloc);
}
assign(__list.cbegin(), __list.cend());
}
return *this;
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
_M_default_insert_after(const_iterator __pos, size_type __n)
{
const_iterator __saved_pos = __pos;
__try
{
for (; __n; --__n)
__pos = emplace_after(__pos);
}
__catch(...)
{
erase_after(__saved_pos, ++__pos);
__throw_exception_again;
}
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
resize(size_type __sz)
{
iterator __k = before_begin();
size_type __len = 0;
while (__k._M_next() != end() && __len < __sz)
{
++__k;
++__len;
}
if (__len == __sz)
erase_after(__k, end());
else
_M_default_insert_after(__k, __sz - __len);
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
resize(size_type __sz, const value_type& __val)
{
iterator __k = before_begin();
size_type __len = 0;
while (__k._M_next() != end() && __len < __sz)
{
++__k;
++__len;
}
if (__len == __sz)
erase_after(__k, end());
else
insert_after(__k, __sz - __len, __val);
}
template<typename _Tp, typename _Alloc>
typename forward_list<_Tp, _Alloc>::iterator
forward_list<_Tp, _Alloc>::
_M_splice_after(const_iterator __pos,
const_iterator __before, const_iterator __last)
{
_Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node);
_Node_base* __b = const_cast<_Node_base*>(__before._M_node);
_Node_base* __end = __b;
while (__end && __end->_M_next != __last._M_node)
__end = __end->_M_next;
if (__b != __end)
return iterator(__tmp->_M_transfer_after(__b, __end));
else
return iterator(__tmp);
}
template<typename _Tp, typename _Alloc>
void
forward_list<_Tp, _Alloc>::
splice_after(const_iterator __pos, forward_list&&,
const_iterator __i) noexcept
{
const_iterator __j = __i;
++__j;
if (__pos == __i || __pos == __j)
return;
_Node_base* __tmp = const_cast<_Node_base*>(__pos._M_node);
__tmp->_M_transfer_after(const_cast<_Node_base*>(__i._M_node),
const_cast<_Node_base*>(__j._M_node));
}
template<typename _Tp, typename _Alloc>
typename forward_list<_Tp, _Alloc>::iterator
forward_list<_Tp, _Alloc>::
insert_after(const_iterator __pos, size_type __n, const _Tp& __val)
{
if (__n)
{
forward_list __tmp(__n, __val, get_allocator());
return _M_splice_after(__pos, __tmp.before_begin(), __tmp.end());
}
else
return iterator(const_cast<_Node_base*>(__pos._M_node));
}
template<typename _Tp, typename _Alloc>
template<typename _InputIterator, typename>
typename forward_list<_Tp, _Alloc>::iterator
forward_list<_Tp, _Alloc>::
insert_after(const_iterator __pos,
_InputIterator __first, _InputIterator __last)
{
forward_list __tmp(__first, __last, get_allocator());
if (!__tmp.empty())
return _M_splice_after(__pos, __tmp.before_begin(), __tmp.end());
else
return iterator(const_cast<_Node_base*>(__pos._M_node));
}
#if __cplusplus > 201703L
# define _GLIBCXX20_ONLY(__expr) __expr
#else
# define _GLIBCXX20_ONLY(__expr)
#endif
template<typename _Tp, typename _Alloc>
auto
forward_list<_Tp, _Alloc>::
remove(const _Tp& __val) -> __remove_return_type
{
size_type __removed __attribute__((__unused__)) = 0;
_Node_base* __curr = &this->_M_impl._M_head;
_Node_base* __extra = nullptr;
while (_Node* __tmp = static_cast<_Node*>(__curr->_M_next))
{
if (*__tmp->_M_valptr() == __val)
{
if (__tmp->_M_valptr() != std::__addressof(__val))
{
this->_M_erase_after(__curr);
_GLIBCXX20_ONLY( __removed++ );
continue;
}
else
__extra = __curr;
}
__curr = __curr->_M_next;
}
if (__extra)
{
this->_M_erase_after(__extra);
_GLIBCXX20_ONLY( __removed++ );
}
return _GLIBCXX20_ONLY( __removed );
}
template<typename _Tp, typename _Alloc>
template<typename _Pred>
auto
forward_list<_Tp, _Alloc>::
remove_if(_Pred __pred) -> __remove_return_type
{
size_type __removed __attribute__((__unused__)) = 0;
_Node_base* __curr = &this->_M_impl._M_head;
while (_Node* __tmp = static_cast<_Node*>(__curr->_M_next))
{
if (__pred(*__tmp->_M_valptr()))
{
this->_M_erase_after(__curr);
_GLIBCXX20_ONLY( __removed++ );
}
else
__curr = __curr->_M_next;
}
return _GLIBCXX20_ONLY( __removed );
}
template<typename _Tp, typename _Alloc>
template<typename _BinPred>
auto
forward_list<_Tp, _Alloc>::
unique(_BinPred __binary_pred) -> __remove_return_type
{
iterator __first = begin();
iterator __last = end();
if (__first == __last)
return _GLIBCXX20_ONLY(0);
size_type __removed __attribute__((__unused__)) = 0;
iterator __next = __first;
while (++__next != __last)
{
if (__binary_pred(*__first, *__next))
{
erase_after(__first);
_GLIBCXX20_ONLY( __removed++ );
}
else
__first = __next;
__next = __first;
}
return _GLIBCXX20_ONLY( __removed );
}
#undef _GLIBCXX20_ONLY
template<typename _Tp, typename _Alloc>
template<typename _Comp>
void
forward_list<_Tp, _Alloc>::
merge(forward_list&& __list, _Comp __comp)
{
_Node_base* __node = &this->_M_impl._M_head;
while (__node->_M_next && __list._M_impl._M_head._M_next)
{
if (__comp(*static_cast<_Node*>
(__list._M_impl._M_head._M_next)->_M_valptr(),
*static_cast<_Node*>
(__node->_M_next)->_M_valptr()))
__node->_M_transfer_after(&__list._M_impl._M_head,
__list._M_impl._M_head._M_next);
__node = __node->_M_next;
}
if (__list._M_impl._M_head._M_next)
*__node = std::move(__list._M_impl._M_head);
}
template<typename _Tp, typename _Alloc>
bool
operator==(const forward_list<_Tp, _Alloc>& __lx,
const forward_list<_Tp, _Alloc>& __ly)
{
// We don't have size() so we need to walk through both lists
// making sure both iterators are valid.
auto __ix = __lx.cbegin();
auto __iy = __ly.cbegin();
while (__ix != __lx.cend() && __iy != __ly.cend())
{
if (!(*__ix == *__iy))
return false;
++__ix;
++__iy;
}
if (__ix == __lx.cend() && __iy == __ly.cend())
return true;
else
return false;
}
template<typename _Tp, class _Alloc>
template<typename _Comp>
void
forward_list<_Tp, _Alloc>::
sort(_Comp __comp)
{
// If `next' is nullptr, return immediately.
_Node* __list = static_cast<_Node*>(this->_M_impl._M_head._M_next);
if (!__list)
return;
unsigned long __insize = 1;
while (1)
{
_Node* __p = __list;
__list = nullptr;
_Node* __tail = nullptr;
// Count number of merges we do in this pass.
unsigned long __nmerges = 0;
while (__p)
{
++__nmerges;
// There exists a merge to be done.
// Step `insize' places along from p.
_Node* __q = __p;
unsigned long __psize = 0;
for (unsigned long __i = 0; __i < __insize; ++__i)
{
++__psize;
__q = static_cast<_Node*>(__q->_M_next);
if (!__q)
break;
}
// If q hasn't fallen off end, we have two lists to merge.
unsigned long __qsize = __insize;
// Now we have two lists; merge them.
while (__psize > 0 || (__qsize > 0 && __q))
{
// Decide whether next node of merge comes from p or q.
_Node* __e;
if (__psize == 0)
{
// p is empty; e must come from q.
__e = __q;
__q = static_cast<_Node*>(__q->_M_next);
--__qsize;
}
else if (__qsize == 0 || !__q)
{
// q is empty; e must come from p.
__e = __p;
__p = static_cast<_Node*>(__p->_M_next);
--__psize;
}
else if (!__comp(*__q->_M_valptr(), *__p->_M_valptr()))
{
// First node of q is not lower; e must come from p.
__e = __p;
__p = static_cast<_Node*>(__p->_M_next);
--__psize;
}
else
{
// First node of q is lower; e must come from q.
__e = __q;
__q = static_cast<_Node*>(__q->_M_next);
--__qsize;
}
// Add the next node to the merged list.
if (__tail)
__tail->_M_next = __e;
else
__list = __e;
__tail = __e;
}
// Now p has stepped `insize' places along, and q has too.
__p = __q;
}
__tail->_M_next = nullptr;
// If we have done only one merge, we're finished.
// Allow for nmerges == 0, the empty list case.
if (__nmerges <= 1)
{
this->_M_impl._M_head._M_next = __list;
return;
}
// Otherwise repeat, merging lists twice the size.
__insize *= 2;
}
}
_GLIBCXX_END_NAMESPACE_CONTAINER
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif /* _FORWARD_LIST_TCC */

View File

@ -0,0 +1,576 @@
// Filesystem directory utilities -*- C++ -*-
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/fs_dir.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{filesystem}
*/
#ifndef _GLIBCXX_FS_DIR_H
#define _GLIBCXX_FS_DIR_H 1
#if __cplusplus >= 201703L
# include <typeinfo>
# include <ext/concurrence.h>
# include <bits/unique_ptr.h>
# include <bits/shared_ptr.h>
#if __cplusplus > 201703L
# include <compare> // std::strong_ordering
#endif
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace filesystem
{
/** @addtogroup filesystem
* @{
*/
/// Information about a file's type and permissions.
class file_status
{
public:
// constructors and destructor
file_status() noexcept : file_status(file_type::none) {}
explicit
file_status(file_type __ft, perms __prms = perms::unknown) noexcept
: _M_type(__ft), _M_perms(__prms) { }
file_status(const file_status&) noexcept = default;
file_status(file_status&&) noexcept = default;
~file_status() = default;
file_status& operator=(const file_status&) noexcept = default;
file_status& operator=(file_status&&) noexcept = default;
// observers
file_type type() const noexcept { return _M_type; }
perms permissions() const noexcept { return _M_perms; }
// modifiers
void type(file_type __ft) noexcept { _M_type = __ft; }
void permissions(perms __prms) noexcept { _M_perms = __prms; }
#if __cpp_lib_three_way_comparison
friend bool
operator==(const file_status&, const file_status&) noexcept = default;
#endif
private:
file_type _M_type;
perms _M_perms;
};
_GLIBCXX_BEGIN_NAMESPACE_CXX11
struct _Dir;
class directory_iterator;
class recursive_directory_iterator;
/// The value type used by directory iterators
class directory_entry
{
public:
// constructors and destructor
directory_entry() noexcept = default;
directory_entry(const directory_entry&) = default;
directory_entry(directory_entry&&) noexcept = default;
explicit
directory_entry(const filesystem::path& __p)
: _M_path(__p)
{ refresh(); }
directory_entry(const filesystem::path& __p, error_code& __ec)
: _M_path(__p)
{
refresh(__ec);
if (__ec)
_M_path.clear();
}
~directory_entry() = default;
// modifiers
directory_entry& operator=(const directory_entry&) = default;
directory_entry& operator=(directory_entry&&) noexcept = default;
void
assign(const filesystem::path& __p)
{
_M_path = __p;
refresh();
}
void
assign(const filesystem::path& __p, error_code& __ec)
{
_M_path = __p;
refresh(__ec);
}
void
replace_filename(const filesystem::path& __p)
{
_M_path.replace_filename(__p);
refresh();
}
void
replace_filename(const filesystem::path& __p, error_code& __ec)
{
_M_path.replace_filename(__p);
refresh(__ec);
}
void
refresh()
{ _M_type = symlink_status().type(); }
void
refresh(error_code& __ec) noexcept
{ _M_type = symlink_status(__ec).type(); }
// observers
const filesystem::path& path() const noexcept { return _M_path; }
operator const filesystem::path& () const noexcept { return _M_path; }
bool
exists() const
{ return filesystem::exists(file_status{_M_file_type()}); }
bool
exists(error_code& __ec) const noexcept
{ return filesystem::exists(file_status{_M_file_type(__ec)}); }
bool
is_block_file() const
{ return _M_file_type() == file_type::block; }
bool
is_block_file(error_code& __ec) const noexcept
{ return _M_file_type(__ec) == file_type::block; }
bool
is_character_file() const
{ return _M_file_type() == file_type::character; }
bool
is_character_file(error_code& __ec) const noexcept
{ return _M_file_type(__ec) == file_type::character; }
bool
is_directory() const
{ return _M_file_type() == file_type::directory; }
bool
is_directory(error_code& __ec) const noexcept
{ return _M_file_type(__ec) == file_type::directory; }
bool
is_fifo() const
{ return _M_file_type() == file_type::fifo; }
bool
is_fifo(error_code& __ec) const noexcept
{ return _M_file_type(__ec) == file_type::fifo; }
bool
is_other() const
{ return filesystem::is_other(file_status{_M_file_type()}); }
bool
is_other(error_code& __ec) const noexcept
{ return filesystem::is_other(file_status{_M_file_type(__ec)}); }
bool
is_regular_file() const
{ return _M_file_type() == file_type::regular; }
bool
is_regular_file(error_code& __ec) const noexcept
{ return _M_file_type(__ec) == file_type::regular; }
bool
is_socket() const
{ return _M_file_type() == file_type::socket; }
bool
is_socket(error_code& __ec) const noexcept
{ return _M_file_type(__ec) == file_type::socket; }
bool
is_symlink() const
{
if (_M_type != file_type::none)
return _M_type == file_type::symlink;
return symlink_status().type() == file_type::symlink;
}
bool
is_symlink(error_code& __ec) const noexcept
{
if (_M_type != file_type::none)
return _M_type == file_type::symlink;
return symlink_status(__ec).type() == file_type::symlink;
}
uintmax_t
file_size() const
{ return filesystem::file_size(_M_path); }
uintmax_t
file_size(error_code& __ec) const noexcept
{ return filesystem::file_size(_M_path, __ec); }
uintmax_t
hard_link_count() const
{ return filesystem::hard_link_count(_M_path); }
uintmax_t
hard_link_count(error_code& __ec) const noexcept
{ return filesystem::hard_link_count(_M_path, __ec); }
file_time_type
last_write_time() const
{ return filesystem::last_write_time(_M_path); }
file_time_type
last_write_time(error_code& __ec) const noexcept
{ return filesystem::last_write_time(_M_path, __ec); }
file_status
status() const
{ return filesystem::status(_M_path); }
file_status
status(error_code& __ec) const noexcept
{ return filesystem::status(_M_path, __ec); }
file_status
symlink_status() const
{ return filesystem::symlink_status(_M_path); }
file_status
symlink_status(error_code& __ec) const noexcept
{ return filesystem::symlink_status(_M_path, __ec); }
bool
operator==(const directory_entry& __rhs) const noexcept
{ return _M_path == __rhs._M_path; }
#if __cpp_lib_three_way_comparison
strong_ordering
operator<=>(const directory_entry& __rhs) const noexcept
{ return _M_path <=> __rhs._M_path; }
#else
bool
operator!=(const directory_entry& __rhs) const noexcept
{ return _M_path != __rhs._M_path; }
bool
operator< (const directory_entry& __rhs) const noexcept
{ return _M_path < __rhs._M_path; }
bool
operator<=(const directory_entry& __rhs) const noexcept
{ return _M_path <= __rhs._M_path; }
bool
operator> (const directory_entry& __rhs) const noexcept
{ return _M_path > __rhs._M_path; }
bool
operator>=(const directory_entry& __rhs) const noexcept
{ return _M_path >= __rhs._M_path; }
#endif
private:
friend class _Dir;
friend class directory_iterator;
friend class recursive_directory_iterator;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 3171. LWG 2989 breaks directory_entry stream insertion
template<typename _CharT, typename _Traits>
friend basic_ostream<_CharT, _Traits>&
operator<<(basic_ostream<_CharT, _Traits>& __os,
const directory_entry& __d)
{ return __os << __d.path(); }
directory_entry(const filesystem::path& __p, file_type __t)
: _M_path(__p), _M_type(__t)
{ }
// Equivalent to status().type() but uses cached value, if any.
file_type
_M_file_type() const
{
if (_M_type != file_type::none && _M_type != file_type::symlink)
return _M_type;
return status().type();
}
// Equivalent to status(__ec).type() but uses cached value, if any.
file_type
_M_file_type(error_code& __ec) const noexcept
{
if (_M_type != file_type::none && _M_type != file_type::symlink)
{
__ec.clear();
return _M_type;
}
return status(__ec).type();
}
filesystem::path _M_path;
file_type _M_type = file_type::none;
};
/// Proxy returned by post-increment on directory iterators.
struct __directory_iterator_proxy
{
const directory_entry& operator*() const& noexcept { return _M_entry; }
directory_entry operator*() && noexcept { return std::move(_M_entry); }
private:
friend class directory_iterator;
friend class recursive_directory_iterator;
explicit
__directory_iterator_proxy(const directory_entry& __e) : _M_entry(__e) { }
directory_entry _M_entry;
};
/// Iterator type for traversing the entries in a single directory.
class directory_iterator
{
public:
typedef directory_entry value_type;
typedef ptrdiff_t difference_type;
typedef const directory_entry* pointer;
typedef const directory_entry& reference;
typedef input_iterator_tag iterator_category;
directory_iterator() = default;
explicit
directory_iterator(const path& __p)
: directory_iterator(__p, directory_options::none, nullptr) { }
directory_iterator(const path& __p, directory_options __options)
: directory_iterator(__p, __options, nullptr) { }
directory_iterator(const path& __p, error_code& __ec)
: directory_iterator(__p, directory_options::none, __ec) { }
directory_iterator(const path& __p, directory_options __options,
error_code& __ec)
: directory_iterator(__p, __options, &__ec) { }
directory_iterator(const directory_iterator& __rhs) = default;
directory_iterator(directory_iterator&& __rhs) noexcept = default;
~directory_iterator() = default;
directory_iterator&
operator=(const directory_iterator& __rhs) = default;
directory_iterator&
operator=(directory_iterator&& __rhs) noexcept = default;
const directory_entry& operator*() const noexcept;
const directory_entry* operator->() const noexcept { return &**this; }
directory_iterator& operator++();
directory_iterator& increment(error_code& __ec);
__directory_iterator_proxy operator++(int)
{
__directory_iterator_proxy __pr{**this};
++*this;
return __pr;
}
private:
directory_iterator(const path&, directory_options, error_code*);
friend bool
operator==(const directory_iterator& __lhs,
const directory_iterator& __rhs) noexcept
{
return !__rhs._M_dir.owner_before(__lhs._M_dir)
&& !__lhs._M_dir.owner_before(__rhs._M_dir);
}
friend bool
operator!=(const directory_iterator& __lhs,
const directory_iterator& __rhs) noexcept
{ return !(__lhs == __rhs); }
friend class recursive_directory_iterator;
std::__shared_ptr<_Dir> _M_dir;
};
/// @relates std::filesystem::directory_iterator @{
/** @brief Enable range-based `for` using directory_iterator.
*
* e.g. `for (auto& entry : std::filesystem::directory_iterator(".")) ...`
*/
inline directory_iterator
begin(directory_iterator __iter) noexcept
{ return __iter; }
/// Return a past-the-end directory_iterator
inline directory_iterator
end(directory_iterator) noexcept
{ return directory_iterator(); }
/// @}
/// Iterator type for recursively traversing a directory hierarchy.
class recursive_directory_iterator
{
public:
typedef directory_entry value_type;
typedef ptrdiff_t difference_type;
typedef const directory_entry* pointer;
typedef const directory_entry& reference;
typedef input_iterator_tag iterator_category;
recursive_directory_iterator() = default;
explicit
recursive_directory_iterator(const path& __p)
: recursive_directory_iterator(__p, directory_options::none, nullptr) { }
recursive_directory_iterator(const path& __p, directory_options __options)
: recursive_directory_iterator(__p, __options, nullptr) { }
recursive_directory_iterator(const path& __p, directory_options __options,
error_code& __ec)
: recursive_directory_iterator(__p, __options, &__ec) { }
recursive_directory_iterator(const path& __p, error_code& __ec)
: recursive_directory_iterator(__p, directory_options::none, &__ec) { }
recursive_directory_iterator(
const recursive_directory_iterator&) = default;
recursive_directory_iterator(recursive_directory_iterator&&) = default;
~recursive_directory_iterator();
// observers
directory_options options() const noexcept;
int depth() const noexcept;
bool recursion_pending() const noexcept;
const directory_entry& operator*() const noexcept;
const directory_entry* operator->() const noexcept { return &**this; }
// modifiers
recursive_directory_iterator&
operator=(const recursive_directory_iterator& __rhs) noexcept;
recursive_directory_iterator&
operator=(recursive_directory_iterator&& __rhs) noexcept;
recursive_directory_iterator& operator++();
recursive_directory_iterator& increment(error_code& __ec);
__directory_iterator_proxy operator++(int)
{
__directory_iterator_proxy __pr{**this};
++*this;
return __pr;
}
void pop();
void pop(error_code&);
void disable_recursion_pending() noexcept;
private:
recursive_directory_iterator(const path&, directory_options, error_code*);
friend bool
operator==(const recursive_directory_iterator& __lhs,
const recursive_directory_iterator& __rhs) noexcept
{
return !__rhs._M_dirs.owner_before(__lhs._M_dirs)
&& !__lhs._M_dirs.owner_before(__rhs._M_dirs);
}
friend bool
operator!=(const recursive_directory_iterator& __lhs,
const recursive_directory_iterator& __rhs) noexcept
{ return !(__lhs == __rhs); }
struct _Dir_stack;
std::__shared_ptr<_Dir_stack> _M_dirs;
};
/// @relates std::filesystem::recursive_directory_iterator @{
/** @brief Enable range-based `for` using recursive_directory_iterator.
*
* e.g. `for (auto& entry : recursive_directory_iterator(".")) ...`
*/
inline recursive_directory_iterator
begin(recursive_directory_iterator __iter) noexcept
{ return __iter; }
/// Return a past-the-end recursive_directory_iterator
inline recursive_directory_iterator
end(recursive_directory_iterator) noexcept
{ return recursive_directory_iterator(); }
/// @}
_GLIBCXX_END_NAMESPACE_CXX11
/// @} group filesystem
} // namespace filesystem
// Use explicit instantiations of these types. Any inconsistency in the
// value of __default_lock_policy between code including this header and
// the library will cause a linker error.
extern template class
__shared_ptr<filesystem::_Dir>;
extern template class
__shared_ptr<filesystem::recursive_directory_iterator::_Dir_stack>;
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++17
#endif // _GLIBCXX_FS_DIR_H

View File

@ -0,0 +1,346 @@
// Filesystem declarations -*- C++ -*-
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/fs_fwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{filesystem}
*/
#ifndef _GLIBCXX_FS_FWD_H
#define _GLIBCXX_FS_FWD_H 1
#if __cplusplus >= 201703L
#include <system_error>
#include <cstdint>
#include <chrono>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @addtogroup filesystem
* @{
*/
/// ISO C++ 2017 namespace for File System library
namespace filesystem
{
#if _GLIBCXX_USE_CXX11_ABI
inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
#endif
class file_status;
_GLIBCXX_BEGIN_NAMESPACE_CXX11
class path;
class filesystem_error;
class directory_entry;
class directory_iterator;
class recursive_directory_iterator;
_GLIBCXX_END_NAMESPACE_CXX11
struct space_info
{
uintmax_t capacity;
uintmax_t free;
uintmax_t available;
#if __cpp_impl_three_way_comparison >= 201907L
friend bool operator==(const space_info&, const space_info&) = default;
#endif
};
enum class file_type : signed char {
none = 0, not_found = -1, regular = 1, directory = 2, symlink = 3,
block = 4, character = 5, fifo = 6, socket = 7, unknown = 8
};
/// Bitmask type
enum class copy_options : unsigned short {
none = 0,
skip_existing = 1, overwrite_existing = 2, update_existing = 4,
recursive = 8,
copy_symlinks = 16, skip_symlinks = 32,
directories_only = 64, create_symlinks = 128, create_hard_links = 256
};
constexpr copy_options
operator&(copy_options __x, copy_options __y) noexcept
{
using __utype = typename std::underlying_type<copy_options>::type;
return static_cast<copy_options>(
static_cast<__utype>(__x) & static_cast<__utype>(__y));
}
constexpr copy_options
operator|(copy_options __x, copy_options __y) noexcept
{
using __utype = typename std::underlying_type<copy_options>::type;
return static_cast<copy_options>(
static_cast<__utype>(__x) | static_cast<__utype>(__y));
}
constexpr copy_options
operator^(copy_options __x, copy_options __y) noexcept
{
using __utype = typename std::underlying_type<copy_options>::type;
return static_cast<copy_options>(
static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
}
constexpr copy_options
operator~(copy_options __x) noexcept
{
using __utype = typename std::underlying_type<copy_options>::type;
return static_cast<copy_options>(~static_cast<__utype>(__x));
}
inline copy_options&
operator&=(copy_options& __x, copy_options __y) noexcept
{ return __x = __x & __y; }
inline copy_options&
operator|=(copy_options& __x, copy_options __y) noexcept
{ return __x = __x | __y; }
inline copy_options&
operator^=(copy_options& __x, copy_options __y) noexcept
{ return __x = __x ^ __y; }
/// Bitmask type
enum class perms : unsigned {
none = 0,
owner_read = 0400,
owner_write = 0200,
owner_exec = 0100,
owner_all = 0700,
group_read = 040,
group_write = 020,
group_exec = 010,
group_all = 070,
others_read = 04,
others_write = 02,
others_exec = 01,
others_all = 07,
all = 0777,
set_uid = 04000,
set_gid = 02000,
sticky_bit = 01000,
mask = 07777,
unknown = 0xFFFF,
};
constexpr perms
operator&(perms __x, perms __y) noexcept
{
using __utype = typename std::underlying_type<perms>::type;
return static_cast<perms>(
static_cast<__utype>(__x) & static_cast<__utype>(__y));
}
constexpr perms
operator|(perms __x, perms __y) noexcept
{
using __utype = typename std::underlying_type<perms>::type;
return static_cast<perms>(
static_cast<__utype>(__x) | static_cast<__utype>(__y));
}
constexpr perms
operator^(perms __x, perms __y) noexcept
{
using __utype = typename std::underlying_type<perms>::type;
return static_cast<perms>(
static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
}
constexpr perms
operator~(perms __x) noexcept
{
using __utype = typename std::underlying_type<perms>::type;
return static_cast<perms>(~static_cast<__utype>(__x));
}
inline perms&
operator&=(perms& __x, perms __y) noexcept
{ return __x = __x & __y; }
inline perms&
operator|=(perms& __x, perms __y) noexcept
{ return __x = __x | __y; }
inline perms&
operator^=(perms& __x, perms __y) noexcept
{ return __x = __x ^ __y; }
/// Bitmask type
enum class perm_options : unsigned {
replace = 0x1,
add = 0x2,
remove = 0x4,
nofollow = 0x8
};
constexpr perm_options
operator&(perm_options __x, perm_options __y) noexcept
{
using __utype = typename std::underlying_type<perm_options>::type;
return static_cast<perm_options>(
static_cast<__utype>(__x) & static_cast<__utype>(__y));
}
constexpr perm_options
operator|(perm_options __x, perm_options __y) noexcept
{
using __utype = typename std::underlying_type<perm_options>::type;
return static_cast<perm_options>(
static_cast<__utype>(__x) | static_cast<__utype>(__y));
}
constexpr perm_options
operator^(perm_options __x, perm_options __y) noexcept
{
using __utype = typename std::underlying_type<perm_options>::type;
return static_cast<perm_options>(
static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
}
constexpr perm_options
operator~(perm_options __x) noexcept
{
using __utype = typename std::underlying_type<perm_options>::type;
return static_cast<perm_options>(~static_cast<__utype>(__x));
}
inline perm_options&
operator&=(perm_options& __x, perm_options __y) noexcept
{ return __x = __x & __y; }
inline perm_options&
operator|=(perm_options& __x, perm_options __y) noexcept
{ return __x = __x | __y; }
inline perm_options&
operator^=(perm_options& __x, perm_options __y) noexcept
{ return __x = __x ^ __y; }
// Bitmask type
enum class directory_options : unsigned char {
none = 0, follow_directory_symlink = 1, skip_permission_denied = 2
};
constexpr directory_options
operator&(directory_options __x, directory_options __y) noexcept
{
using __utype = typename std::underlying_type<directory_options>::type;
return static_cast<directory_options>(
static_cast<__utype>(__x) & static_cast<__utype>(__y));
}
constexpr directory_options
operator|(directory_options __x, directory_options __y) noexcept
{
using __utype = typename std::underlying_type<directory_options>::type;
return static_cast<directory_options>(
static_cast<__utype>(__x) | static_cast<__utype>(__y));
}
constexpr directory_options
operator^(directory_options __x, directory_options __y) noexcept
{
using __utype = typename std::underlying_type<directory_options>::type;
return static_cast<directory_options>(
static_cast<__utype>(__x) ^ static_cast<__utype>(__y));
}
constexpr directory_options
operator~(directory_options __x) noexcept
{
using __utype = typename std::underlying_type<directory_options>::type;
return static_cast<directory_options>(~static_cast<__utype>(__x));
}
inline directory_options&
operator&=(directory_options& __x, directory_options __y) noexcept
{ return __x = __x & __y; }
inline directory_options&
operator|=(directory_options& __x, directory_options __y) noexcept
{ return __x = __x | __y; }
inline directory_options&
operator^=(directory_options& __x, directory_options __y) noexcept
{ return __x = __x ^ __y; }
using file_time_type = __file_clock::time_point;
// operational functions
void copy(const path& __from, const path& __to, copy_options __options);
void copy(const path& __from, const path& __to, copy_options __options,
error_code&);
bool copy_file(const path& __from, const path& __to, copy_options __option);
bool copy_file(const path& __from, const path& __to, copy_options __option,
error_code&);
path current_path();
bool exists(file_status) noexcept;
bool is_other(file_status) noexcept;
uintmax_t file_size(const path&);
uintmax_t file_size(const path&, error_code&) noexcept;
uintmax_t hard_link_count(const path&);
uintmax_t hard_link_count(const path&, error_code&) noexcept;
file_time_type last_write_time(const path&);
file_time_type last_write_time(const path&, error_code&) noexcept;
void permissions(const path&, perms, perm_options, error_code&) noexcept;
path proximate(const path& __p, const path& __base, error_code& __ec);
path proximate(const path& __p, const path& __base, error_code& __ec);
path relative(const path& __p, const path& __base, error_code& __ec);
file_status status(const path&);
file_status status(const path&, error_code&) noexcept;
bool status_known(file_status) noexcept;
file_status symlink_status(const path&);
file_status symlink_status(const path&, error_code&) noexcept;
bool is_regular_file(file_status) noexcept;
bool is_symlink(file_status) noexcept;
} // namespace filesystem
/// @}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++17
#endif // _GLIBCXX_FS_FWD_H

View File

@ -0,0 +1,313 @@
// Filesystem operational functions -*- C++ -*-
// Copyright (C) 2014-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your __option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/fs_fwd.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{filesystem}
*/
#ifndef _GLIBCXX_FS_OPS_H
#define _GLIBCXX_FS_OPS_H 1
#if __cplusplus >= 201703L
#include <cstdint>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace filesystem
{
/** @addtogroup filesystem
* @{
*/
path absolute(const path& __p);
path absolute(const path& __p, error_code& __ec);
path canonical(const path& __p);
path canonical(const path& __p, error_code& __ec);
inline void
copy(const path& __from, const path& __to)
{ copy(__from, __to, copy_options::none); }
inline void
copy(const path& __from, const path& __to, error_code& __ec)
{ copy(__from, __to, copy_options::none, __ec); }
void copy(const path& __from, const path& __to, copy_options __options);
void copy(const path& __from, const path& __to, copy_options __options,
error_code& __ec);
inline bool
copy_file(const path& __from, const path& __to)
{ return copy_file(__from, __to, copy_options::none); }
inline bool
copy_file(const path& __from, const path& __to, error_code& __ec)
{ return copy_file(__from, __to, copy_options::none, __ec); }
bool copy_file(const path& __from, const path& __to, copy_options __option);
bool copy_file(const path& __from, const path& __to, copy_options __option,
error_code& __ec);
void copy_symlink(const path& __existing_symlink, const path& __new_symlink);
void copy_symlink(const path& __existing_symlink, const path& __new_symlink,
error_code& __ec) noexcept;
bool create_directories(const path& __p);
bool create_directories(const path& __p, error_code& __ec);
bool create_directory(const path& __p);
bool create_directory(const path& __p, error_code& __ec) noexcept;
bool create_directory(const path& __p, const path& attributes);
bool create_directory(const path& __p, const path& attributes,
error_code& __ec) noexcept;
void create_directory_symlink(const path& __to, const path& __new_symlink);
void create_directory_symlink(const path& __to, const path& __new_symlink,
error_code& __ec) noexcept;
void create_hard_link(const path& __to, const path& __new_hard_link);
void create_hard_link(const path& __to, const path& __new_hard_link,
error_code& __ec) noexcept;
void create_symlink(const path& __to, const path& __new_symlink);
void create_symlink(const path& __to, const path& __new_symlink,
error_code& __ec) noexcept;
path current_path();
path current_path(error_code& __ec);
void current_path(const path& __p);
void current_path(const path& __p, error_code& __ec) noexcept;
bool
equivalent(const path& __p1, const path& __p2);
bool
equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept;
inline bool
exists(file_status __s) noexcept
{ return status_known(__s) && __s.type() != file_type::not_found; }
inline bool
exists(const path& __p)
{ return exists(status(__p)); }
inline bool
exists(const path& __p, error_code& __ec) noexcept
{
auto __s = status(__p, __ec);
if (status_known(__s))
{
__ec.clear();
return __s.type() != file_type::not_found;
}
return false;
}
uintmax_t file_size(const path& __p);
uintmax_t file_size(const path& __p, error_code& __ec) noexcept;
uintmax_t hard_link_count(const path& __p);
uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept;
inline bool
is_block_file(file_status __s) noexcept
{ return __s.type() == file_type::block; }
inline bool
is_block_file(const path& __p)
{ return is_block_file(status(__p)); }
inline bool
is_block_file(const path& __p, error_code& __ec) noexcept
{ return is_block_file(status(__p, __ec)); }
inline bool
is_character_file(file_status __s) noexcept
{ return __s.type() == file_type::character; }
inline bool
is_character_file(const path& __p)
{ return is_character_file(status(__p)); }
inline bool
is_character_file(const path& __p, error_code& __ec) noexcept
{ return is_character_file(status(__p, __ec)); }
inline bool
is_directory(file_status __s) noexcept
{ return __s.type() == file_type::directory; }
inline bool
is_directory(const path& __p)
{ return is_directory(status(__p)); }
inline bool
is_directory(const path& __p, error_code& __ec) noexcept
{ return is_directory(status(__p, __ec)); }
bool is_empty(const path& __p);
bool is_empty(const path& __p, error_code& __ec);
inline bool
is_fifo(file_status __s) noexcept
{ return __s.type() == file_type::fifo; }
inline bool
is_fifo(const path& __p)
{ return is_fifo(status(__p)); }
inline bool
is_fifo(const path& __p, error_code& __ec) noexcept
{ return is_fifo(status(__p, __ec)); }
inline bool
is_other(file_status __s) noexcept
{
return exists(__s) && !is_regular_file(__s) && !is_directory(__s)
&& !is_symlink(__s);
}
inline bool
is_other(const path& __p)
{ return is_other(status(__p)); }
inline bool
is_other(const path& __p, error_code& __ec) noexcept
{ return is_other(status(__p, __ec)); }
inline bool
is_regular_file(file_status __s) noexcept
{ return __s.type() == file_type::regular; }
inline bool
is_regular_file(const path& __p)
{ return is_regular_file(status(__p)); }
inline bool
is_regular_file(const path& __p, error_code& __ec) noexcept
{ return is_regular_file(status(__p, __ec)); }
inline bool
is_socket(file_status __s) noexcept
{ return __s.type() == file_type::socket; }
inline bool
is_socket(const path& __p)
{ return is_socket(status(__p)); }
inline bool
is_socket(const path& __p, error_code& __ec) noexcept
{ return is_socket(status(__p, __ec)); }
inline bool
is_symlink(file_status __s) noexcept
{ return __s.type() == file_type::symlink; }
inline bool
is_symlink(const path& __p)
{ return is_symlink(symlink_status(__p)); }
inline bool
is_symlink(const path& __p, error_code& __ec) noexcept
{ return is_symlink(symlink_status(__p, __ec)); }
file_time_type last_write_time(const path& __p);
file_time_type last_write_time(const path& __p, error_code& __ec) noexcept;
void last_write_time(const path& __p, file_time_type __new_time);
void last_write_time(const path& __p, file_time_type __new_time,
error_code& __ec) noexcept;
void
permissions(const path& __p, perms __prms,
perm_options __opts = perm_options::replace);
inline void
permissions(const path& __p, perms __prms, error_code& __ec) noexcept
{ permissions(__p, __prms, perm_options::replace, __ec); }
void
permissions(const path& __p, perms __prms, perm_options __opts,
error_code& __ec) noexcept;
inline path proximate(const path& __p, error_code& __ec)
{ return proximate(__p, current_path(), __ec); }
path proximate(const path& __p, const path& __base = current_path());
path proximate(const path& __p, const path& __base, error_code& __ec);
path read_symlink(const path& __p);
path read_symlink(const path& __p, error_code& __ec);
inline path relative(const path& __p, error_code& __ec)
{ return relative(__p, current_path(), __ec); }
path relative(const path& __p, const path& __base = current_path());
path relative(const path& __p, const path& __base, error_code& __ec);
bool remove(const path& __p);
bool remove(const path& __p, error_code& __ec) noexcept;
uintmax_t remove_all(const path& __p);
uintmax_t remove_all(const path& __p, error_code& __ec);
void rename(const path& __from, const path& __to);
void rename(const path& __from, const path& __to, error_code& __ec) noexcept;
void resize_file(const path& __p, uintmax_t __size);
void resize_file(const path& __p, uintmax_t __size, error_code& __ec) noexcept;
space_info space(const path& __p);
space_info space(const path& __p, error_code& __ec) noexcept;
file_status status(const path& __p);
file_status status(const path& __p, error_code& __ec) noexcept;
inline bool status_known(file_status __s) noexcept
{ return __s.type() != file_type::none; }
file_status symlink_status(const path& __p);
file_status symlink_status(const path& __p, error_code& __ec) noexcept;
path temp_directory_path();
path temp_directory_path(error_code& __ec);
path weakly_canonical(const path& __p);
path weakly_canonical(const path& __p, error_code& __ec);
/// @} group filesystem
} // namespace filesystem
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++17
#endif // _GLIBCXX_FS_OPS_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,115 @@
// Function-Based Exception Support -*- C++ -*-
// Copyright (C) 2001-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/functexcept.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{exception}
*
* This header provides support for -fno-exceptions.
*/
//
// ISO C++ 14882: 19.1 Exception classes
//
#ifndef _FUNCTEXCEPT_H
#define _FUNCTEXCEPT_H 1
#include <bits/c++config.h>
#include <bits/exception_defines.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Helper for exception objects in <except>
void
__throw_bad_exception(void) __attribute__((__noreturn__));
// Helper for exception objects in <new>
void
__throw_bad_alloc(void) __attribute__((__noreturn__));
// Helper for exception objects in <typeinfo>
void
__throw_bad_cast(void) __attribute__((__noreturn__));
void
__throw_bad_typeid(void) __attribute__((__noreturn__));
// Helpers for exception objects in <stdexcept>
void
__throw_logic_error(const char*) __attribute__((__noreturn__));
void
__throw_domain_error(const char*) __attribute__((__noreturn__));
void
__throw_invalid_argument(const char*) __attribute__((__noreturn__));
void
__throw_length_error(const char*) __attribute__((__noreturn__));
void
__throw_out_of_range(const char*) __attribute__((__noreturn__));
void
__throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__))
__attribute__((__format__(__gnu_printf__, 1, 2)));
void
__throw_runtime_error(const char*) __attribute__((__noreturn__));
void
__throw_range_error(const char*) __attribute__((__noreturn__));
void
__throw_overflow_error(const char*) __attribute__((__noreturn__));
void
__throw_underflow_error(const char*) __attribute__((__noreturn__));
// Helpers for exception objects in <ios>
void
__throw_ios_failure(const char*) __attribute__((__noreturn__));
void
__throw_ios_failure(const char*, int) __attribute__((__noreturn__));
// Helpers for exception objects in <system_error>
void
__throw_system_error(int) __attribute__((__noreturn__));
// Helpers for exception objects in <future>
void
__throw_future_error(int) __attribute__((__noreturn__));
// Helpers for exception objects in <functional>
void
__throw_bad_function_call() __attribute__((__noreturn__));
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,289 @@
// functional_hash.h header -*- C++ -*-
// Copyright (C) 2007-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/functional_hash.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _FUNCTIONAL_HASH_H
#define _FUNCTIONAL_HASH_H 1
#pragma GCC system_header
#include <bits/hash_bytes.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @defgroup hashes Hashes
* @ingroup functors
*
* Hashing functors taking a variable type and returning a @c std::size_t.
*
* @{
*/
template<typename _Result, typename _Arg>
struct __hash_base
{
typedef _Result result_type _GLIBCXX17_DEPRECATED;
typedef _Arg argument_type _GLIBCXX17_DEPRECATED;
};
/// Primary class template hash.
template<typename _Tp>
struct hash;
template<typename _Tp, typename = void>
struct __poison_hash
{
static constexpr bool __enable_hash_call = false;
private:
// Private rather than deleted to be non-trivially-copyable.
__poison_hash(__poison_hash&&);
~__poison_hash();
};
template<typename _Tp>
struct __poison_hash<_Tp, __void_t<decltype(hash<_Tp>()(declval<_Tp>()))>>
{
static constexpr bool __enable_hash_call = true;
};
// Helper struct for SFINAE-poisoning non-enum types.
template<typename _Tp, bool = is_enum<_Tp>::value>
struct __hash_enum
{
private:
// Private rather than deleted to be non-trivially-copyable.
__hash_enum(__hash_enum&&);
~__hash_enum();
};
// Helper struct for hash with enum types.
template<typename _Tp>
struct __hash_enum<_Tp, true> : public __hash_base<size_t, _Tp>
{
size_t
operator()(_Tp __val) const noexcept
{
using __type = typename underlying_type<_Tp>::type;
return hash<__type>{}(static_cast<__type>(__val));
}
};
/// Primary class template hash, usable for enum types only.
// Use with non-enum types still SFINAES.
template<typename _Tp>
struct hash : __hash_enum<_Tp>
{ };
/// Partial specializations for pointer types.
template<typename _Tp>
struct hash<_Tp*> : public __hash_base<size_t, _Tp*>
{
size_t
operator()(_Tp* __p) const noexcept
{ return reinterpret_cast<size_t>(__p); }
};
// Explicit specializations for integer types.
#define _Cxx_hashtable_define_trivial_hash(_Tp) \
template<> \
struct hash<_Tp> : public __hash_base<size_t, _Tp> \
{ \
size_t \
operator()(_Tp __val) const noexcept \
{ return static_cast<size_t>(__val); } \
};
/// Explicit specialization for bool.
_Cxx_hashtable_define_trivial_hash(bool)
/// Explicit specialization for char.
_Cxx_hashtable_define_trivial_hash(char)
/// Explicit specialization for signed char.
_Cxx_hashtable_define_trivial_hash(signed char)
/// Explicit specialization for unsigned char.
_Cxx_hashtable_define_trivial_hash(unsigned char)
/// Explicit specialization for wchar_t.
_Cxx_hashtable_define_trivial_hash(wchar_t)
#ifdef _GLIBCXX_USE_CHAR8_T
/// Explicit specialization for char8_t.
_Cxx_hashtable_define_trivial_hash(char8_t)
#endif
/// Explicit specialization for char16_t.
_Cxx_hashtable_define_trivial_hash(char16_t)
/// Explicit specialization for char32_t.
_Cxx_hashtable_define_trivial_hash(char32_t)
/// Explicit specialization for short.
_Cxx_hashtable_define_trivial_hash(short)
/// Explicit specialization for int.
_Cxx_hashtable_define_trivial_hash(int)
/// Explicit specialization for long.
_Cxx_hashtable_define_trivial_hash(long)
/// Explicit specialization for long long.
_Cxx_hashtable_define_trivial_hash(long long)
/// Explicit specialization for unsigned short.
_Cxx_hashtable_define_trivial_hash(unsigned short)
/// Explicit specialization for unsigned int.
_Cxx_hashtable_define_trivial_hash(unsigned int)
/// Explicit specialization for unsigned long.
_Cxx_hashtable_define_trivial_hash(unsigned long)
/// Explicit specialization for unsigned long long.
_Cxx_hashtable_define_trivial_hash(unsigned long long)
#ifdef __GLIBCXX_TYPE_INT_N_0
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_0)
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_0 unsigned)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_1
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_1)
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_1 unsigned)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_2
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_2)
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_2 unsigned)
#endif
#ifdef __GLIBCXX_TYPE_INT_N_3
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3)
_Cxx_hashtable_define_trivial_hash(__GLIBCXX_TYPE_INT_N_3 unsigned)
#endif
#undef _Cxx_hashtable_define_trivial_hash
struct _Hash_impl
{
static size_t
hash(const void* __ptr, size_t __clength,
size_t __seed = static_cast<size_t>(0xc70f6907UL))
{ return _Hash_bytes(__ptr, __clength, __seed); }
template<typename _Tp>
static size_t
hash(const _Tp& __val)
{ return hash(&__val, sizeof(__val)); }
template<typename _Tp>
static size_t
__hash_combine(const _Tp& __val, size_t __hash)
{ return hash(&__val, sizeof(__val), __hash); }
};
// A hash function similar to FNV-1a (see PR59406 for how it differs).
struct _Fnv_hash_impl
{
static size_t
hash(const void* __ptr, size_t __clength,
size_t __seed = static_cast<size_t>(2166136261UL))
{ return _Fnv_hash_bytes(__ptr, __clength, __seed); }
template<typename _Tp>
static size_t
hash(const _Tp& __val)
{ return hash(&__val, sizeof(__val)); }
template<typename _Tp>
static size_t
__hash_combine(const _Tp& __val, size_t __hash)
{ return hash(&__val, sizeof(__val), __hash); }
};
/// Specialization for float.
template<>
struct hash<float> : public __hash_base<size_t, float>
{
size_t
operator()(float __val) const noexcept
{
// 0 and -0 both hash to zero.
return __val != 0.0f ? std::_Hash_impl::hash(__val) : 0;
}
};
/// Specialization for double.
template<>
struct hash<double> : public __hash_base<size_t, double>
{
size_t
operator()(double __val) const noexcept
{
// 0 and -0 both hash to zero.
return __val != 0.0 ? std::_Hash_impl::hash(__val) : 0;
}
};
/// Specialization for long double.
template<>
struct hash<long double>
: public __hash_base<size_t, long double>
{
_GLIBCXX_PURE size_t
operator()(long double __val) const noexcept;
};
#if __cplusplus >= 201703L
template<>
struct hash<nullptr_t> : public __hash_base<size_t, nullptr_t>
{
size_t
operator()(nullptr_t) const noexcept
{ return 0; }
};
#endif
/// @} group hashes
// Hint about performance of hash functor. If not fast the hash-based
// containers will cache the hash code.
// Default behavior is to consider that hashers are fast unless specified
// otherwise.
template<typename _Hash>
struct __is_fast_hash : public std::true_type
{ };
template<>
struct __is_fast_hash<hash<long double>> : public std::false_type
{ };
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // _FUNCTIONAL_HASH_H

View File

@ -0,0 +1,185 @@
// The template and inlines for the -*- C++ -*- gslice class.
// Copyright (C) 1997-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/gslice.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _GSLICE_H
#define _GSLICE_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup numeric_arrays
* @{
*/
/**
* @brief Class defining multi-dimensional subset of an array.
*
* The slice class represents a multi-dimensional subset of an array,
* specified by three parameter sets: start offset, size array, and stride
* array. The start offset is the index of the first element of the array
* that is part of the subset. The size and stride array describe each
* dimension of the slice. Size is the number of elements in that
* dimension, and stride is the distance in the array between successive
* elements in that dimension. Each dimension's size and stride is taken
* to begin at an array element described by the previous dimension. The
* size array and stride array must be the same size.
*
* For example, if you have offset==3, stride[0]==11, size[1]==3,
* stride[1]==3, then slice[0,0]==array[3], slice[0,1]==array[6],
* slice[0,2]==array[9], slice[1,0]==array[14], slice[1,1]==array[17],
* slice[1,2]==array[20].
*/
class gslice
{
public:
/// Construct an empty slice.
gslice();
/**
* @brief Construct a slice.
*
* Constructs a slice with as many dimensions as the length of the @a l
* and @a s arrays.
*
* @param __o Offset in array of first element.
* @param __l Array of dimension lengths.
* @param __s Array of dimension strides between array elements.
*/
gslice(size_t __o, const valarray<size_t>& __l,
const valarray<size_t>& __s);
// XXX: the IS says the copy-ctor and copy-assignment operators are
// synthesized by the compiler but they are just unsuitable
// for a ref-counted semantic
/// Copy constructor.
gslice(const gslice&);
/// Destructor.
~gslice();
// XXX: See the note above.
/// Assignment operator.
gslice& operator=(const gslice&);
/// Return array offset of first slice element.
size_t start() const;
/// Return array of sizes of slice dimensions.
valarray<size_t> size() const;
/// Return array of array strides for each dimension.
valarray<size_t> stride() const;
private:
struct _Indexer
{
size_t _M_count;
size_t _M_start;
valarray<size_t> _M_size;
valarray<size_t> _M_stride;
valarray<size_t> _M_index; // Linear array of referenced indices
_Indexer()
: _M_count(1), _M_start(0), _M_size(), _M_stride(), _M_index() {}
_Indexer(size_t, const valarray<size_t>&,
const valarray<size_t>&);
void
_M_increment_use()
{ ++_M_count; }
size_t
_M_decrement_use()
{ return --_M_count; }
};
_Indexer* _M_index;
template<typename _Tp> friend class valarray;
};
inline size_t
gslice::start() const
{ return _M_index ? _M_index->_M_start : 0; }
inline valarray<size_t>
gslice::size() const
{ return _M_index ? _M_index->_M_size : valarray<size_t>(); }
inline valarray<size_t>
gslice::stride() const
{ return _M_index ? _M_index->_M_stride : valarray<size_t>(); }
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 543. valarray slice default constructor
inline
gslice::gslice()
: _M_index(new gslice::_Indexer()) {}
inline
gslice::gslice(size_t __o, const valarray<size_t>& __l,
const valarray<size_t>& __s)
: _M_index(new gslice::_Indexer(__o, __l, __s)) {}
inline
gslice::gslice(const gslice& __g)
: _M_index(__g._M_index)
{ if (_M_index) _M_index->_M_increment_use(); }
inline
gslice::~gslice()
{
if (_M_index && _M_index->_M_decrement_use() == 0)
delete _M_index;
}
inline gslice&
gslice::operator=(const gslice& __g)
{
if (__g._M_index)
__g._M_index->_M_increment_use();
if (_M_index && _M_index->_M_decrement_use() == 0)
delete _M_index;
_M_index = __g._M_index;
return *this;
}
/// @} group numeric_arrays
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _GSLICE_H */

View File

@ -0,0 +1,223 @@
// The template and inlines for the -*- C++ -*- gslice_array class.
// Copyright (C) 1997-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/gslice_array.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _GSLICE_ARRAY_H
#define _GSLICE_ARRAY_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup numeric_arrays
* @{
*/
/**
* @brief Reference to multi-dimensional subset of an array.
*
* A gslice_array is a reference to the actual elements of an array
* specified by a gslice. The way to get a gslice_array is to call
* operator[](gslice) on a valarray. The returned gslice_array then
* permits carrying operations out on the referenced subset of elements in
* the original valarray. For example, operator+=(valarray) will add
* values to the subset of elements in the underlying valarray this
* gslice_array refers to.
*
* @param Tp Element type.
*/
template<typename _Tp>
class gslice_array
{
public:
typedef _Tp value_type;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 253. valarray helper functions are almost entirely useless
/// Copy constructor. Both slices refer to the same underlying array.
gslice_array(const gslice_array&);
/// Assignment operator. Assigns slice elements to corresponding
/// elements of @a a.
gslice_array& operator=(const gslice_array&);
/// Assign slice elements to corresponding elements of @a v.
void operator=(const valarray<_Tp>&) const;
/// Multiply slice elements by corresponding elements of @a v.
void operator*=(const valarray<_Tp>&) const;
/// Divide slice elements by corresponding elements of @a v.
void operator/=(const valarray<_Tp>&) const;
/// Modulo slice elements by corresponding elements of @a v.
void operator%=(const valarray<_Tp>&) const;
/// Add corresponding elements of @a v to slice elements.
void operator+=(const valarray<_Tp>&) const;
/// Subtract corresponding elements of @a v from slice elements.
void operator-=(const valarray<_Tp>&) const;
/// Logical xor slice elements with corresponding elements of @a v.
void operator^=(const valarray<_Tp>&) const;
/// Logical and slice elements with corresponding elements of @a v.
void operator&=(const valarray<_Tp>&) const;
/// Logical or slice elements with corresponding elements of @a v.
void operator|=(const valarray<_Tp>&) const;
/// Left shift slice elements by corresponding elements of @a v.
void operator<<=(const valarray<_Tp>&) const;
/// Right shift slice elements by corresponding elements of @a v.
void operator>>=(const valarray<_Tp>&) const;
/// Assign all slice elements to @a t.
void operator=(const _Tp&) const;
template<class _Dom>
void operator=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator*=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator/=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator%=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator+=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator-=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator^=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator&=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator|=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator<<=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator>>=(const _Expr<_Dom, _Tp>&) const;
private:
_Array<_Tp> _M_array;
const valarray<size_t>& _M_index;
friend class valarray<_Tp>;
gslice_array(_Array<_Tp>, const valarray<size_t>&);
#if __cplusplus < 201103L
// not implemented
gslice_array();
#else
public:
gslice_array() = delete;
#endif
};
template<typename _Tp>
inline
gslice_array<_Tp>::gslice_array(_Array<_Tp> __a,
const valarray<size_t>& __i)
: _M_array(__a), _M_index(__i) {}
template<typename _Tp>
inline
gslice_array<_Tp>::gslice_array(const gslice_array<_Tp>& __a)
: _M_array(__a._M_array), _M_index(__a._M_index) {}
template<typename _Tp>
inline gslice_array<_Tp>&
gslice_array<_Tp>::operator=(const gslice_array<_Tp>& __a)
{
std::__valarray_copy(_Array<_Tp>(__a._M_array),
_Array<size_t>(__a._M_index), _M_index.size(),
_M_array, _Array<size_t>(_M_index));
return *this;
}
template<typename _Tp>
inline void
gslice_array<_Tp>::operator=(const _Tp& __t) const
{
std::__valarray_fill(_M_array, _Array<size_t>(_M_index),
_M_index.size(), __t);
}
template<typename _Tp>
inline void
gslice_array<_Tp>::operator=(const valarray<_Tp>& __v) const
{
std::__valarray_copy(_Array<_Tp>(__v), __v.size(),
_M_array, _Array<size_t>(_M_index));
}
template<typename _Tp>
template<class _Dom>
inline void
gslice_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const
{
std::__valarray_copy (__e, _M_index.size(), _M_array,
_Array<size_t>(_M_index));
}
#undef _DEFINE_VALARRAY_OPERATOR
#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \
template<typename _Tp> \
inline void \
gslice_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const \
{ \
_Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), \
_Array<_Tp>(__v), __v.size()); \
} \
\
template<typename _Tp> \
template<class _Dom> \
inline void \
gslice_array<_Tp>::operator _Op##= (const _Expr<_Dom, _Tp>& __e) const\
{ \
_Array_augmented_##_Name(_M_array, _Array<size_t>(_M_index), __e,\
_M_index.size()); \
}
_DEFINE_VALARRAY_OPERATOR(*, __multiplies)
_DEFINE_VALARRAY_OPERATOR(/, __divides)
_DEFINE_VALARRAY_OPERATOR(%, __modulus)
_DEFINE_VALARRAY_OPERATOR(+, __plus)
_DEFINE_VALARRAY_OPERATOR(-, __minus)
_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor)
_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and)
_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or)
_DEFINE_VALARRAY_OPERATOR(<<, __shift_left)
_DEFINE_VALARRAY_OPERATOR(>>, __shift_right)
#undef _DEFINE_VALARRAY_OPERATOR
/// @} group numeric_arrays
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _GSLICE_ARRAY_H */

View File

@ -0,0 +1,59 @@
// Declarations for hash functions. -*- C++ -*-
// Copyright (C) 2010-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/hash_bytes.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _HASH_BYTES_H
#define _HASH_BYTES_H 1
#pragma GCC system_header
#include <bits/c++config.h>
namespace std
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
// Hash function implementation for the nontrivial specialization.
// All of them are based on a primitive that hashes a pointer to a
// byte array. The actual hash algorithm is not guaranteed to stay
// the same from release to release -- it may be updated or tuned to
// improve hash quality or speed.
size_t
_Hash_bytes(const void* __ptr, size_t __len, size_t __seed);
// A similar hash primitive, using the FNV hash algorithm. This
// algorithm is guaranteed to stay the same from release to release.
// (although it might not produce the same values on different
// machines.)
size_t
_Fnv_hash_bytes(const void* __ptr, size_t __len, size_t __seed);
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif

View File

@ -0,0 +1,212 @@
// The template and inlines for the -*- C++ -*- indirect_array class.
// Copyright (C) 1997-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file bits/indirect_array.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{valarray}
*/
// Written by Gabriel Dos Reis <Gabriel.Dos-Reis@DPTMaths.ENS-Cachan.Fr>
#ifndef _INDIRECT_ARRAY_H
#define _INDIRECT_ARRAY_H 1
#pragma GCC system_header
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup numeric_arrays
* @{
*/
/**
* @brief Reference to arbitrary subset of an array.
*
* An indirect_array is a reference to the actual elements of an array
* specified by an ordered array of indices. The way to get an
* indirect_array is to call operator[](valarray<size_t>) on a valarray.
* The returned indirect_array then permits carrying operations out on the
* referenced subset of elements in the original valarray.
*
* For example, if an indirect_array is obtained using the array (4,2,0) as
* an argument, and then assigned to an array containing (1,2,3), then the
* underlying array will have array[0]==3, array[2]==2, and array[4]==1.
*
* @param Tp Element type.
*/
template <class _Tp>
class indirect_array
{
public:
typedef _Tp value_type;
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 253. valarray helper functions are almost entirely useless
/// Copy constructor. Both slices refer to the same underlying array.
indirect_array(const indirect_array&);
/// Assignment operator. Assigns elements to corresponding elements
/// of @a a.
indirect_array& operator=(const indirect_array&);
/// Assign slice elements to corresponding elements of @a v.
void operator=(const valarray<_Tp>&) const;
/// Multiply slice elements by corresponding elements of @a v.
void operator*=(const valarray<_Tp>&) const;
/// Divide slice elements by corresponding elements of @a v.
void operator/=(const valarray<_Tp>&) const;
/// Modulo slice elements by corresponding elements of @a v.
void operator%=(const valarray<_Tp>&) const;
/// Add corresponding elements of @a v to slice elements.
void operator+=(const valarray<_Tp>&) const;
/// Subtract corresponding elements of @a v from slice elements.
void operator-=(const valarray<_Tp>&) const;
/// Logical xor slice elements with corresponding elements of @a v.
void operator^=(const valarray<_Tp>&) const;
/// Logical and slice elements with corresponding elements of @a v.
void operator&=(const valarray<_Tp>&) const;
/// Logical or slice elements with corresponding elements of @a v.
void operator|=(const valarray<_Tp>&) const;
/// Left shift slice elements by corresponding elements of @a v.
void operator<<=(const valarray<_Tp>&) const;
/// Right shift slice elements by corresponding elements of @a v.
void operator>>=(const valarray<_Tp>&) const;
/// Assign all slice elements to @a t.
void operator= (const _Tp&) const;
// ~indirect_array();
template<class _Dom>
void operator=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator*=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator/=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator%=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator+=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator-=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator^=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator&=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator|=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator<<=(const _Expr<_Dom, _Tp>&) const;
template<class _Dom>
void operator>>=(const _Expr<_Dom, _Tp>&) const;
private:
/// Copy constructor. Both slices refer to the same underlying array.
indirect_array(_Array<_Tp>, size_t, _Array<size_t>);
friend class valarray<_Tp>;
friend class gslice_array<_Tp>;
const size_t _M_sz;
const _Array<size_t> _M_index;
const _Array<_Tp> _M_array;
// not implemented
indirect_array();
};
template<typename _Tp>
inline
indirect_array<_Tp>::indirect_array(const indirect_array<_Tp>& __a)
: _M_sz(__a._M_sz), _M_index(__a._M_index), _M_array(__a._M_array) {}
template<typename _Tp>
inline
indirect_array<_Tp>::indirect_array(_Array<_Tp> __a, size_t __s,
_Array<size_t> __i)
: _M_sz(__s), _M_index(__i), _M_array(__a) {}
template<typename _Tp>
inline indirect_array<_Tp>&
indirect_array<_Tp>::operator=(const indirect_array<_Tp>& __a)
{
std::__valarray_copy(__a._M_array, _M_sz, __a._M_index, _M_array,
_M_index);
return *this;
}
template<typename _Tp>
inline void
indirect_array<_Tp>::operator=(const _Tp& __t) const
{ std::__valarray_fill(_M_array, _M_index, _M_sz, __t); }
template<typename _Tp>
inline void
indirect_array<_Tp>::operator=(const valarray<_Tp>& __v) const
{ std::__valarray_copy(_Array<_Tp>(__v), _M_sz, _M_array, _M_index); }
template<typename _Tp>
template<class _Dom>
inline void
indirect_array<_Tp>::operator=(const _Expr<_Dom, _Tp>& __e) const
{ std::__valarray_copy(__e, _M_sz, _M_array, _M_index); }
#undef _DEFINE_VALARRAY_OPERATOR
#define _DEFINE_VALARRAY_OPERATOR(_Op, _Name) \
template<typename _Tp> \
inline void \
indirect_array<_Tp>::operator _Op##=(const valarray<_Tp>& __v) const\
{ \
_Array_augmented_##_Name(_M_array, _M_index, _Array<_Tp>(__v), _M_sz); \
} \
\
template<typename _Tp> \
template<class _Dom> \
inline void \
indirect_array<_Tp>::operator _Op##=(const _Expr<_Dom,_Tp>& __e) const\
{ \
_Array_augmented_##_Name(_M_array, _M_index, __e, _M_sz); \
}
_DEFINE_VALARRAY_OPERATOR(*, __multiplies)
_DEFINE_VALARRAY_OPERATOR(/, __divides)
_DEFINE_VALARRAY_OPERATOR(%, __modulus)
_DEFINE_VALARRAY_OPERATOR(+, __plus)
_DEFINE_VALARRAY_OPERATOR(-, __minus)
_DEFINE_VALARRAY_OPERATOR(^, __bitwise_xor)
_DEFINE_VALARRAY_OPERATOR(&, __bitwise_and)
_DEFINE_VALARRAY_OPERATOR(|, __bitwise_or)
_DEFINE_VALARRAY_OPERATOR(<<, __shift_left)
_DEFINE_VALARRAY_OPERATOR(>>, __shift_right)
#undef _DEFINE_VALARRAY_OPERATOR
/// @} group numeric_arrays
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif /* _INDIRECT_ARRAY_H */

View File

@ -0,0 +1,163 @@
// Implementation of INVOKE -*- C++ -*-
// Copyright (C) 2016-2020 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/** @file include/bits/invoke.h
* This is an internal header file, included by other library headers.
* Do not attempt to use it directly. @headername{functional}
*/
#ifndef _GLIBCXX_INVOKE_H
#define _GLIBCXX_INVOKE_H 1
#pragma GCC system_header
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
#include <type_traits>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @addtogroup utilities
* @{
*/
// Used by __invoke_impl instead of std::forward<_Tp> so that a
// reference_wrapper is converted to an lvalue-reference.
template<typename _Tp, typename _Up = typename __inv_unwrap<_Tp>::type>
constexpr _Up&&
__invfwd(typename remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Up&&>(__t); }
template<typename _Res, typename _Fn, typename... _Args>
constexpr _Res
__invoke_impl(__invoke_other, _Fn&& __f, _Args&&... __args)
{ return std::forward<_Fn>(__f)(std::forward<_Args>(__args)...); }
template<typename _Res, typename _MemFun, typename _Tp, typename... _Args>
constexpr _Res
__invoke_impl(__invoke_memfun_ref, _MemFun&& __f, _Tp&& __t,
_Args&&... __args)
{ return (__invfwd<_Tp>(__t).*__f)(std::forward<_Args>(__args)...); }
template<typename _Res, typename _MemFun, typename _Tp, typename... _Args>
constexpr _Res
__invoke_impl(__invoke_memfun_deref, _MemFun&& __f, _Tp&& __t,
_Args&&... __args)
{
return ((*std::forward<_Tp>(__t)).*__f)(std::forward<_Args>(__args)...);
}
template<typename _Res, typename _MemPtr, typename _Tp>
constexpr _Res
__invoke_impl(__invoke_memobj_ref, _MemPtr&& __f, _Tp&& __t)
{ return __invfwd<_Tp>(__t).*__f; }
template<typename _Res, typename _MemPtr, typename _Tp>
constexpr _Res
__invoke_impl(__invoke_memobj_deref, _MemPtr&& __f, _Tp&& __t)
{ return (*std::forward<_Tp>(__t)).*__f; }
/// Invoke a callable object.
template<typename _Callable, typename... _Args>
constexpr typename __invoke_result<_Callable, _Args...>::type
__invoke(_Callable&& __fn, _Args&&... __args)
noexcept(__is_nothrow_invocable<_Callable, _Args...>::value)
{
using __result = __invoke_result<_Callable, _Args...>;
using __type = typename __result::type;
using __tag = typename __result::__invoke_type;
return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
}
#if __cplusplus >= 201703L
// INVOKE<R>: Invoke a callable object and convert the result to R.
template<typename _Res, typename _Callable, typename... _Args>
constexpr enable_if_t<is_invocable_r_v<_Res, _Callable, _Args...>, _Res>
__invoke_r(_Callable&& __fn, _Args&&... __args)
noexcept(is_nothrow_invocable_r_v<_Res, _Callable, _Args...>)
{
using __result = __invoke_result<_Callable, _Args...>;
using __type = typename __result::type;
using __tag = typename __result::__invoke_type;
if constexpr (is_void_v<_Res>)
std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
else
return std::__invoke_impl<__type>(__tag{},
std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
}
#else // C++11
template<typename _Res, typename _Callable, typename... _Args>
using __can_invoke_as_void = __enable_if_t<
__and_<is_void<_Res>, __is_invocable<_Callable, _Args...>>::value,
_Res
>;
template<typename _Res, typename _Callable, typename... _Args>
using __can_invoke_as_nonvoid = __enable_if_t<
__and_<__not_<is_void<_Res>>,
is_convertible<typename __invoke_result<_Callable, _Args...>::type,
_Res>
>::value,
_Res
>;
// INVOKE<R>: Invoke a callable object and convert the result to R.
template<typename _Res, typename _Callable, typename... _Args>
constexpr __can_invoke_as_nonvoid<_Res, _Callable, _Args...>
__invoke_r(_Callable&& __fn, _Args&&... __args)
{
using __result = __invoke_result<_Callable, _Args...>;
using __type = typename __result::type;
using __tag = typename __result::__invoke_type;
return std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
}
// INVOKE<R> when R is cv void
template<typename _Res, typename _Callable, typename... _Args>
_GLIBCXX14_CONSTEXPR __can_invoke_as_void<_Res, _Callable, _Args...>
__invoke_r(_Callable&& __fn, _Args&&... __args)
{
using __result = __invoke_result<_Callable, _Args...>;
using __type = typename __result::type;
using __tag = typename __result::__invoke_type;
std::__invoke_impl<__type>(__tag{}, std::forward<_Callable>(__fn),
std::forward<_Args>(__args)...);
}
#endif // C++11
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++11
#endif // _GLIBCXX_INVOKE_H

Some files were not shown because too many files have changed in this diff Show More