Add tools
This commit is contained in:
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/ar
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/ar
Executable file
Binary file not shown.
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/as
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/as
Executable file
Binary file not shown.
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/ld
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/ld
Executable file
Binary file not shown.
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/ld.bfd
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/ld.bfd
Executable file
Binary file not shown.
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/nm
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/nm
Executable file
Binary file not shown.
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/objcopy
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/objcopy
Executable file
Binary file not shown.
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/objdump
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/objdump
Executable file
Binary file not shown.
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/ranlib
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/ranlib
Executable file
Binary file not shown.
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/readelf
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/readelf
Executable file
Binary file not shown.
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/strip
Executable file
BIN
tools/bin/x86_64-unknown-redox/toolchain/x86_64-unknown-redox/bin/strip
Executable file
Binary file not shown.
@@ -0,0 +1,60 @@
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG>
|
||||
* Copyright (2) 2014 The FreeBSD Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: head/lib/libc/aarch64/_fpmath.h 281197 2015-04-07 09:52:14Z andrew $
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
union IEEEl2bits {
|
||||
long double e;
|
||||
struct {
|
||||
uint64_t manl :64;
|
||||
uint64_t manh :48;
|
||||
unsigned int exp :15;
|
||||
unsigned int sign :1;
|
||||
} bits;
|
||||
/* TODO andrew: Check the packing here */
|
||||
struct {
|
||||
uint64_t manl :64;
|
||||
uint64_t manh :48;
|
||||
unsigned int expsign :16;
|
||||
} xbits;
|
||||
};
|
||||
|
||||
#define LDBL_NBIT 0
|
||||
#define LDBL_IMPLICIT_NBIT
|
||||
#define mask_nbit_l(u) ((void)0)
|
||||
|
||||
#define LDBL_MANH_SIZE 48
|
||||
#define LDBL_MANL_SIZE 64
|
||||
|
||||
#define LDBL_TO_ARRAY32(u, a) do { \
|
||||
(a)[0] = (uint32_t)(u).bits.manl; \
|
||||
(a)[1] = (uint32_t)((u).bits.manl >> 32); \
|
||||
(a)[2] = (uint32_t)(u).bits.manh; \
|
||||
(a)[3] = (uint32_t)((u).bits.manh >> 32); \
|
||||
} while(0)
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _ALLOCA_H
|
||||
#define _ALLOCA_H
|
||||
|
||||
#define alloca(size) __builtin_alloca (size)
|
||||
|
||||
#endif /* _ALLOCA_H */
|
||||
@@ -0,0 +1,55 @@
|
||||
/*-
|
||||
* Copyright (c) 2002, 2003 David Schultz <das@FreeBSD.ORG>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD: src/lib/libc/amd64/_fpmath.h,v 1.7 2008/01/17 16:39:06 bde Exp $
|
||||
*/
|
||||
|
||||
union IEEEl2bits {
|
||||
long double e;
|
||||
struct {
|
||||
unsigned int manl :32;
|
||||
unsigned int manh :32;
|
||||
unsigned int exp :15;
|
||||
unsigned int sign :1;
|
||||
unsigned int junkl :16;
|
||||
unsigned int junkh :32;
|
||||
} bits;
|
||||
struct {
|
||||
unsigned long man :64;
|
||||
unsigned int expsign :16;
|
||||
unsigned long junk :48;
|
||||
} xbits;
|
||||
};
|
||||
|
||||
#define LDBL_NBIT 0x80000000
|
||||
#define mask_nbit_l(u) ((u).bits.manh &= ~LDBL_NBIT)
|
||||
|
||||
#define LDBL_MANH_SIZE 32
|
||||
#define LDBL_MANL_SIZE 32
|
||||
|
||||
#define LDBL_TO_ARRAY32(u, a) do { \
|
||||
(a)[0] = (uint32_t)(u).bits.manl; \
|
||||
(a)[1] = (uint32_t)(u).bits.manh; \
|
||||
} while (0)
|
||||
@@ -0,0 +1,34 @@
|
||||
#ifndef _AARCH64_USER_H
|
||||
#define _AARCH64_USER_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct user_regs_struct {
|
||||
unsigned long long regs[31];
|
||||
unsigned long long sp;
|
||||
unsigned long long pc;
|
||||
unsigned long long pstate;
|
||||
};
|
||||
|
||||
struct user_fpsimd_struct {
|
||||
double vregs[32];
|
||||
unsigned int fpsr;
|
||||
unsigned int fpcr;
|
||||
};
|
||||
|
||||
typedef unsigned long elf_gregset_t[34];
|
||||
|
||||
typedef unsigned long elf_greg_t;
|
||||
|
||||
typedef struct user_fpsimd_struct elf_fpregset_t;
|
||||
|
||||
void _cbindgen_export_aarch64_user(struct user_regs_struct a,
|
||||
struct user_fpsimd_struct b,
|
||||
elf_gregset_t c,
|
||||
elf_greg_t d,
|
||||
elf_fpregset_t e);
|
||||
|
||||
#endif /* _AARCH64_USER_H */
|
||||
@@ -0,0 +1,41 @@
|
||||
#ifndef _RISCV64_USER_H
|
||||
#define _RISCV64_USER_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct user_regs_struct {
|
||||
unsigned long regs[31];
|
||||
unsigned long pc;
|
||||
};
|
||||
|
||||
struct user_fpregs_f_struct {
|
||||
float fpregs[32];
|
||||
unsigned int fcsr;
|
||||
};
|
||||
|
||||
struct user_fpregs_g_struct {
|
||||
double fpregs[32];
|
||||
unsigned int fcsr;
|
||||
};
|
||||
|
||||
struct user_fpregs_struct {
|
||||
struct user_fpregs_f_struct f_regs;
|
||||
struct user_fpregs_g_struct g_regs;
|
||||
};
|
||||
|
||||
typedef struct user_regs_struct elf_gregset_t;
|
||||
|
||||
typedef unsigned long elf_greg_t;
|
||||
|
||||
typedef struct user_fpregs_struct elf_fpregset_t;
|
||||
|
||||
void _cbindgen_only_generates_structs_if_they_are_mentioned_which_is_dumb_riscv64_user(struct user_regs_struct a,
|
||||
struct user_fpregs_struct b,
|
||||
elf_gregset_t c,
|
||||
elf_greg_t d,
|
||||
elf_fpregset_t e);
|
||||
|
||||
#endif /* _RISCV64_USER_H */
|
||||
@@ -0,0 +1,84 @@
|
||||
#ifndef _X64_USER_H
|
||||
#define _X64_USER_H
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct user_fpregs_struct {
|
||||
uint16_t cwd;
|
||||
uint16_t swd;
|
||||
uint16_t ftw;
|
||||
uint16_t fop;
|
||||
uint64_t rip;
|
||||
uint64_t rdp;
|
||||
uint32_t mxcsr;
|
||||
uint32_t mxcr_mask;
|
||||
uint32_t st_space[32];
|
||||
uint32_t xmm_space[64];
|
||||
uint32_t padding[24];
|
||||
};
|
||||
|
||||
struct user_regs_struct {
|
||||
unsigned long r15;
|
||||
unsigned long r14;
|
||||
unsigned long r13;
|
||||
unsigned long r12;
|
||||
unsigned long rbp;
|
||||
unsigned long rbx;
|
||||
unsigned long r11;
|
||||
unsigned long r10;
|
||||
unsigned long r9;
|
||||
unsigned long r8;
|
||||
unsigned long rax;
|
||||
unsigned long rcx;
|
||||
unsigned long rdx;
|
||||
unsigned long rsi;
|
||||
unsigned long rdi;
|
||||
unsigned long orig_rax;
|
||||
unsigned long rip;
|
||||
unsigned long cs;
|
||||
unsigned long eflags;
|
||||
unsigned long rsp;
|
||||
unsigned long ss;
|
||||
unsigned long fs_base;
|
||||
unsigned long gs_base;
|
||||
unsigned long ds;
|
||||
unsigned long es;
|
||||
unsigned long fs;
|
||||
unsigned long gs;
|
||||
};
|
||||
|
||||
struct user {
|
||||
struct user_regs_struct regs;
|
||||
int u_fpvalid;
|
||||
struct user_fpregs_struct i387;
|
||||
unsigned long u_tsize;
|
||||
unsigned long u_dsize;
|
||||
unsigned long u_ssize;
|
||||
unsigned long start_code;
|
||||
unsigned long start_stack;
|
||||
long signal;
|
||||
int reserved;
|
||||
struct user_regs_struct *u_ar0;
|
||||
struct user_fpregs_struct *u_fpstate;
|
||||
unsigned long magic;
|
||||
char u_comm[32];
|
||||
unsigned long u_debugreg[8];
|
||||
};
|
||||
|
||||
typedef unsigned long elf_gregset_t[27];
|
||||
|
||||
typedef unsigned long elf_greg_t;
|
||||
|
||||
typedef struct user_fpregs_struct elf_fpregset_t;
|
||||
|
||||
void _cbindgen_export_x86_user(struct user_fpregs_struct a,
|
||||
struct user_regs_struct b,
|
||||
struct user c,
|
||||
elf_gregset_t d,
|
||||
elf_greg_t e,
|
||||
elf_fpregset_t f);
|
||||
|
||||
#endif /* _X64_USER_H */
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef _ARPA_INET_H
|
||||
#define _ARPA_INET_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
uint32_t htonl(uint32_t hostlong);
|
||||
|
||||
uint16_t htons(uint16_t hostshort);
|
||||
|
||||
uint32_t ntohl(uint32_t netlong);
|
||||
|
||||
uint16_t ntohs(uint16_t netshort);
|
||||
|
||||
int inet_aton(const char *cp, struct in_addr *inp);
|
||||
|
||||
const char *inet_ntoa(struct in_addr addr);
|
||||
|
||||
int inet_pton(int domain, const char *src, void *dest);
|
||||
|
||||
const char *inet_ntop(int domain, const void *src, char *dest, socklen_t size);
|
||||
|
||||
in_addr_t inet_addr(const char *cp);
|
||||
|
||||
in_addr_t inet_lnaof(struct in_addr input);
|
||||
|
||||
struct in_addr inet_makeaddr(in_addr_t net, in_addr_t host);
|
||||
|
||||
in_addr_t inet_netof(struct in_addr input);
|
||||
|
||||
in_addr_t inet_network(char *cp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* _ARPA_INET_H */
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef _RELIBC_ASSERT_H
|
||||
#define _RELIBC_ASSERT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
void __assert_fail(const char *func,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *cond) __attribute__((noreturn));
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif /* _RELIBC_ASSERT_H */
|
||||
|
||||
#include <bits/assert.h>
|
||||
@@ -0,0 +1,11 @@
|
||||
// Do not use include guard, to ensure assert is always defined
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define assert(cond) (void) 0
|
||||
#else
|
||||
# define assert(cond) \
|
||||
((void)((cond) || (__assert_fail(__func__, __FILE__, __LINE__, #cond), 0)))
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
#ifndef _BITS_CTYPE_H
|
||||
#define _BITS_CTYPE_H
|
||||
|
||||
#define _tolower(c) tolower(c)
|
||||
#define _toupper(c) toupper(c)
|
||||
|
||||
#endif /* _BITS_CTYPE_H */
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef _BITS_DIRENT_H
|
||||
#define _BITS_DIRENT_H
|
||||
|
||||
// Shamelessly stolen from musl
|
||||
#define DT_UNKNOWN 0
|
||||
#define DT_FIFO 1
|
||||
#define DT_CHR 2
|
||||
#define DT_DIR 4
|
||||
#define DT_BLK 6
|
||||
#define DT_REG 8
|
||||
#define DT_LNK 10
|
||||
#define DT_SOCK 12
|
||||
#define DT_WHT 14
|
||||
#define IFTODT(x) ((x)>>12 & 017)
|
||||
#define DTTOIF(x) ((x)<<12)
|
||||
|
||||
#endif /* _BITS_DIRENT_H */
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef _BITS_ELF_H
|
||||
#define _BITS_ELF_H
|
||||
#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
|
||||
#define ELF32_ST_TYPE(val) ((val) & 0xf)
|
||||
#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
|
||||
|
||||
#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
|
||||
#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
|
||||
#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type))
|
||||
|
||||
|
||||
#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
|
||||
#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
|
||||
|
||||
#define ELF32_R_SYM(val) ((val) >> 8)
|
||||
#define ELF32_R_TYPE(val) ((val) & 0xff)
|
||||
#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
|
||||
|
||||
#define ELF64_R_SYM(i) ((i) >> 32)
|
||||
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
|
||||
#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type))
|
||||
|
||||
#define DT_VALRNGHI 0x6ffffdff
|
||||
#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag))
|
||||
|
||||
#define DT_ADDRRNGHI 0x6ffffeff
|
||||
#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag))
|
||||
|
||||
#define DT_VERNEEDNUM 0x6fffffff
|
||||
#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag))
|
||||
|
||||
#define ELF32_M_SYM(info) ((info) >> 8)
|
||||
#define ELF32_M_SIZE(info) ((unsigned char) (info))
|
||||
#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size))
|
||||
|
||||
#define ELF64_M_SYM(info) ELF32_M_SYM (info)
|
||||
#define ELF64_M_SIZE(info) ELF32_M_SIZE (info)
|
||||
#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size)
|
||||
|
||||
#endif /* ifdef _BITS_ELF_H*/
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef _BITS_ERRNO_H
|
||||
#define _BITS_ERRNO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ENOTSUP EOPNOTSUPP
|
||||
|
||||
#define errno (*__errno_location())
|
||||
#define program_invocation_name (*__program_invocation_name())
|
||||
#define program_invocation_short_name (*__program_invocation_short_name())
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* _BITS_ERRNO_H */
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef _BITS_FCNTL_H
|
||||
#define _BITS_FCNTL_H
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef _BITS_FLOAT_H
|
||||
#define _BITS_FLOAT_H
|
||||
|
||||
#define FLT_ROUNDS (flt_rounds())
|
||||
|
||||
// Shamelessly copy pasted from musl:
|
||||
|
||||
#define FLT_TRUE_MIN 1.40129846432481707092e-45F
|
||||
#define FLT_MIN 1.17549435082228750797e-38F
|
||||
#define FLT_MAX 3.40282346638528859812e+38F
|
||||
#define FLT_EPSILON 1.1920928955078125e-07F
|
||||
|
||||
#define FLT_MANT_DIG 24
|
||||
#define FLT_MIN_EXP (-125)
|
||||
#define FLT_MAX_EXP 128
|
||||
#define FLT_HAS_SUBNORM 1
|
||||
|
||||
#define FLT_DIG 6
|
||||
#define FLT_DECIMAL_DIG 9
|
||||
#define FLT_MIN_10_EXP (-37)
|
||||
#define FLT_MAX_10_EXP 38
|
||||
|
||||
#define DBL_TRUE_MIN 4.94065645841246544177e-324
|
||||
#define DBL_MIN 2.22507385850720138309e-308
|
||||
#define DBL_MAX 1.79769313486231570815e+308
|
||||
#define DBL_EPSILON 2.22044604925031308085e-16
|
||||
|
||||
#define DBL_MANT_DIG 53
|
||||
#define DBL_MIN_EXP (-1021)
|
||||
#define DBL_MAX_EXP 1024
|
||||
#define DBL_HAS_SUBNORM 1
|
||||
|
||||
#define DBL_DIG 15
|
||||
#define DBL_DECIMAL_DIG 17
|
||||
#define DBL_MIN_10_EXP (-307)
|
||||
#define DBL_MAX_10_EXP 308
|
||||
|
||||
#define LDBL_HAS_SUBNORM 1
|
||||
#define LDBL_DECIMAL_DIG DECIMAL_DIG
|
||||
|
||||
// TODO: Support more architectures than x86_64 here:
|
||||
#define LDBL_TRUE_MIN 3.6451995318824746025e-4951L
|
||||
#define LDBL_MIN 3.3621031431120935063e-4932L
|
||||
#define LDBL_MAX 1.1897314953572317650e+4932L
|
||||
#define LDBL_EPSILON 1.0842021724855044340e-19L
|
||||
|
||||
#define LDBL_MANT_DIG 64
|
||||
#define LDBL_MIN_EXP (-16381)
|
||||
#define LDBL_MAX_EXP 16384
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,195 @@
|
||||
#ifndef _BITS_INTTYPE_H
|
||||
#define _BITS_INTTYPE_H
|
||||
|
||||
#define PRId8 "hhd"
|
||||
#define PRId16 "hd"
|
||||
#define PRId32 "d"
|
||||
#define PRId64 "ld"
|
||||
|
||||
#define PRIdLEAST8 "hhd"
|
||||
#define PRIdLEAST16 "hd"
|
||||
#define PRIdLEAST32 "d"
|
||||
#define PRIdLEAST64 "ld"
|
||||
|
||||
#define PRIdFAST8 "hhd"
|
||||
#define PRIdFAST16 "hd"
|
||||
#define PRIdFAST32 "d"
|
||||
#define PRIdFAST64 "ld"
|
||||
|
||||
#define PRIi8 "hhi"
|
||||
#define PRIi16 "hi"
|
||||
#define PRIi32 "i"
|
||||
#define PRIi64 "li"
|
||||
|
||||
#define PRIiLEAST8 "hhi"
|
||||
#define PRIiLEAST16 "hi"
|
||||
#define PRIiLEAST32 "i"
|
||||
#define PRIiLEAST64 "li"
|
||||
|
||||
#define PRIiFAST8 "hhi"
|
||||
#define PRIiFAST16 "hi"
|
||||
#define PRIiFAST32 "i"
|
||||
#define PRIiFAST64 "li"
|
||||
|
||||
#define PRIo8 "hho"
|
||||
#define PRIo16 "ho"
|
||||
#define PRIo32 "o"
|
||||
#define PRIo64 "lo"
|
||||
|
||||
#define PRIoLEAST8 "hho"
|
||||
#define PRIoLEAST16 "ho"
|
||||
#define PRIoLEAST32 "o"
|
||||
#define PRIoLEAST64 "lo"
|
||||
|
||||
#define PRIoFAST8 "hho"
|
||||
#define PRIoFAST16 "ho"
|
||||
#define PRIoFAST32 "o"
|
||||
#define PRIoFAST64 "lo"
|
||||
|
||||
#define PRIu8 "hhu"
|
||||
#define PRIu16 "hu"
|
||||
#define PRIu32 "u"
|
||||
#define PRIu64 "lu"
|
||||
|
||||
#define PRIuLEAST8 "hhu"
|
||||
#define PRIuLEAST16 "hu"
|
||||
#define PRIuLEAST32 "u"
|
||||
#define PRIuLEAST64 "lu"
|
||||
|
||||
#define PRIuFAST8 "hhu"
|
||||
#define PRIuFAST16 "hu"
|
||||
#define PRIuFAST32 "u"
|
||||
#define PRIuFAST64 "lu"
|
||||
|
||||
#define PRIx8 "hhx"
|
||||
#define PRIx16 "hx"
|
||||
#define PRIx32 "x"
|
||||
#define PRIx64 "lx"
|
||||
|
||||
#define PRIxLEAST8 "hhx"
|
||||
#define PRIxLEAST16 "hx"
|
||||
#define PRIxLEAST32 "x"
|
||||
#define PRIxLEAST64 "lx"
|
||||
|
||||
#define PRIxFAST8 "hhx"
|
||||
#define PRIxFAST16 "hx"
|
||||
#define PRIxFAST32 "x"
|
||||
#define PRIxFAST64 "lx"
|
||||
|
||||
#define PRIX8 "hhX"
|
||||
#define PRIX16 "hX"
|
||||
#define PRIX32 "X"
|
||||
#define PRIX64 "lX"
|
||||
|
||||
#define PRIXLEAST8 "hhX"
|
||||
#define PRIXLEAST16 "hX"
|
||||
#define PRIXLEAST32 "X"
|
||||
#define PRIXLEAST64 "lX"
|
||||
|
||||
#define PRIXFAST8 "hhX"
|
||||
#define PRIXFAST16 "hX"
|
||||
#define PRIXFAST32 "X"
|
||||
#define PRIXFAST64 "lX"
|
||||
|
||||
#define PRIdMAX "jd"
|
||||
#define PRIiMAX "ji"
|
||||
#define PRIoMAX "jo"
|
||||
#define PRIuMAX "ju"
|
||||
#define PRIxMAX "jx"
|
||||
#define PRIXMAX "jX"
|
||||
|
||||
#define PRIdPTR "td"
|
||||
#define PRIiPTR "ti"
|
||||
#define PRIoPTR "to"
|
||||
#define PRIuPTR "tu"
|
||||
#define PRIxPTR "tx"
|
||||
#define PRIXPTR "tX"
|
||||
|
||||
#define SCNd8 PRId8
|
||||
#define SCNd16 PRId16
|
||||
#define SCNd32 PRId32
|
||||
#define SCNd64 PRId64
|
||||
|
||||
#define SCNdLEAST8 PRIdLEAST8
|
||||
#define SCNdLEAST16 PRIdLEAST16
|
||||
#define SCNdLEAST32 PRIdLEAST32
|
||||
#define SCNdLEAST64 PRIdLEAST64
|
||||
|
||||
#define SCNdFAST8 PRIdFAST8
|
||||
#define SCNdFAST16 PRIdFAST16
|
||||
#define SCNdFAST32 PRIdFAST32
|
||||
#define SCNdFAST64 PRIdFAST64
|
||||
|
||||
#define SCNi8 PRIi8
|
||||
#define SCNi16 PRIi16
|
||||
#define SCNi32 PRIi32
|
||||
#define SCNi64 PRIi64
|
||||
|
||||
#define SCNiLEAST8 PRIiLEAST8
|
||||
#define SCNiLEAST16 PRIiLEAST16
|
||||
#define SCNiLEAST32 PRIiLEAST32
|
||||
#define SCNiLEAST64 PRIiLEAST64
|
||||
|
||||
#define SCNiFAST8 PRIiFAST8
|
||||
#define SCNiFAST16 PRIiFAST16
|
||||
#define SCNiFAST32 PRIiFAST32
|
||||
#define SCNiFAST64 PRIiFAST64
|
||||
|
||||
#define SCNo8 PRIo8
|
||||
#define SCNo16 PRIo16
|
||||
#define SCNo32 PRIo32
|
||||
#define SCNo64 PRIo64
|
||||
|
||||
#define SCNoLEAST8 PRIoLEAST8
|
||||
#define SCNoLEAST16 PRIoLEAST16
|
||||
#define SCNoLEAST32 PRIoLEAST32
|
||||
#define SCNoLEAST64 PRIoLEAST64
|
||||
|
||||
#define SCNoFAST8 PRIoFAST8
|
||||
#define SCNoFAST16 PRIoFAST16
|
||||
#define SCNoFAST32 PRIoFAST32
|
||||
#define SCNoFAST64 PRIoFAST64
|
||||
|
||||
#define SCNu8 PRIu8
|
||||
#define SCNu16 PRIu16
|
||||
#define SCNu32 PRIu32
|
||||
#define SCNu64 PRIu64
|
||||
|
||||
#define SCNuLEAST8 PRIuLEAST8
|
||||
#define SCNuLEAST16 PRIuLEAST16
|
||||
#define SCNuLEAST32 PRIuLEAST32
|
||||
#define SCNuLEAST64 PRIuLEAST64
|
||||
|
||||
#define SCNuFAST8 PRIuFAST8
|
||||
#define SCNuFAST16 PRIuFAST16
|
||||
#define SCNuFAST32 PRIuFAST32
|
||||
#define SCNuFAST64 PRIuFAST64
|
||||
|
||||
#define SCNx8 PRIx8
|
||||
#define SCNx16 PRIx16
|
||||
#define SCNx32 PRIx32
|
||||
#define SCNx64 PRIx64
|
||||
|
||||
#define SCNxLEAST8 PRIxLEAST8
|
||||
#define SCNxLEAST16 PRIxLEAST16
|
||||
#define SCNxLEAST32 PRIxLEAST32
|
||||
#define SCNxLEAST64 PRIxLEAST64
|
||||
|
||||
#define SCNxFAST8 PRIxFAST8
|
||||
#define SCNxFAST16 PRIxFAST16
|
||||
#define SCNxFAST32 PRIxFAST32
|
||||
#define SCNxFAST64 PRIxFAST64
|
||||
|
||||
#define SCNdMAX PRIdMAX
|
||||
#define SCNiMAX PRIiMAX
|
||||
#define SCNoMAX PRIoMAX
|
||||
#define SCNuMAX PRIuMAX
|
||||
#define SCNxMAX PRIxMAX
|
||||
|
||||
#define SCNdPTR PRIdPTR
|
||||
#define SCNiPTR PRIiPTR
|
||||
#define SCNoPTR PRIoPTR
|
||||
#define SCNuPTR PRIuPTR
|
||||
#define SCNxPTR PRIxPTR
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef _BITS_LIMIT_H
|
||||
#define _BITS_LIMIT_H
|
||||
|
||||
#define CHAR_BIT __CHAR_BIT__
|
||||
#ifdef __CHAR_MAX__
|
||||
# define CHAR_MAX __CHAR_MAX__
|
||||
#else
|
||||
# define CHAR_MAX 0xFF
|
||||
#endif
|
||||
#define CHAR_MIN 0
|
||||
#define INT_MAX __INT_MAX__
|
||||
#define INT_MIN (-INT_MAX - 1)
|
||||
#define LLONG_MAX __LONG_LONG_MAX__
|
||||
#define LLONG_MIN (-LLONG_MAX - 1)
|
||||
#define LONG_BIT __LONG_WIDTH__
|
||||
#define LONG_MAX __LONG_MAX__
|
||||
#define LONG_MIN (-LONG_MAX - 1)
|
||||
#define SCHAR_MAX __SCHAR_MAX__
|
||||
#define SCHAR_MIN (-SCHAR_MAX - 1)
|
||||
#define SHRT_MAX __SHRT_MAX__
|
||||
#define SHRT_MIN (-SHRT_MAX - 1)
|
||||
|
||||
// TODO: These might not be accurate on all platforms
|
||||
#define SSIZE_MAX 0x7fffffffffffffff
|
||||
#define UCHAR_MAX 255
|
||||
#define UINT_MAX 0xffffffff
|
||||
#define ULLONG_MAX 0xffffffffffffffff
|
||||
#define ULONG_MAX 0xffffffffffffffff
|
||||
#define USHRT_MAX 0xffffffffffffffff
|
||||
#define WORD_BIT 32
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,7 @@
|
||||
#define LC_ALL 0
|
||||
#define LC_COLLATE 1
|
||||
#define LC_CTYPE 2
|
||||
#define LC_MESSAGES 3
|
||||
#define LC_MONETARY 4
|
||||
#define LC_NUMERIC 5
|
||||
#define LC_TIME 6
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _BITS_NETDB_H
|
||||
#define _BITS_NETDB_H
|
||||
|
||||
# define h_addr h_addr_list[0] /* Address, for backward compatibility.*/
|
||||
|
||||
#endif /* _BITS_NETDB_H */
|
||||
@@ -0,0 +1,77 @@
|
||||
#ifndef _BITS_NETINET_IN_H
|
||||
#define _BITS_NETINET_IN_H
|
||||
|
||||
extern const struct in6_addr in6addr_any;
|
||||
extern const struct in6_addr in6addr_loopback;
|
||||
#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
|
||||
#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
|
||||
|
||||
// from musl {
|
||||
#define IN6_IS_ADDR_UNSPECIFIED(a) \
|
||||
(((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
|
||||
((uint32_t *) (a))[2] == 0 && ((uint32_t *) (a))[3] == 0)
|
||||
|
||||
#define IN6_IS_ADDR_LOOPBACK(a) \
|
||||
(((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
|
||||
((uint32_t *) (a))[2] == 0 && \
|
||||
((uint8_t *) (a))[12] == 0 && ((uint8_t *) (a))[13] == 0 && \
|
||||
((uint8_t *) (a))[14] == 0 && ((uint8_t *) (a))[15] == 1 )
|
||||
|
||||
#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff)
|
||||
|
||||
#define IN6_IS_ADDR_LINKLOCAL(a) \
|
||||
((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0x80)
|
||||
|
||||
#define IN6_IS_ADDR_SITELOCAL(a) \
|
||||
((((uint8_t *) (a))[0]) == 0xfe && (((uint8_t *) (a))[1] & 0xc0) == 0xc0)
|
||||
|
||||
#define IN6_IS_ADDR_V4MAPPED(a) \
|
||||
(((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
|
||||
((uint8_t *) (a))[8] == 0 && ((uint8_t *) (a))[9] == 0 && \
|
||||
((uint8_t *) (a))[10] == 0xff && ((uint8_t *) (a))[11] == 0xff)
|
||||
|
||||
#define IN6_IS_ADDR_V4COMPAT(a) \
|
||||
(((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
|
||||
((uint32_t *) (a))[2] == 0 && ((uint8_t *) (a))[15] > 1)
|
||||
|
||||
#define IN6_IS_ADDR_MC_NODELOCAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x1))
|
||||
|
||||
#define IN6_IS_ADDR_MC_LINKLOCAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x2))
|
||||
|
||||
#define IN6_IS_ADDR_MC_SITELOCAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x5))
|
||||
|
||||
#define IN6_IS_ADDR_MC_ORGLOCAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0x8))
|
||||
|
||||
#define IN6_IS_ADDR_MC_GLOBAL(a) \
|
||||
(IN6_IS_ADDR_MULTICAST(a) && ((((uint8_t *) (a))[1] & 0xf) == 0xe))
|
||||
|
||||
#define __ARE_4_EQUAL(a,b) \
|
||||
(!( (0[a]-0[b]) | (1[a]-1[b]) | (2[a]-2[b]) | (3[a]-3[b]) ))
|
||||
#define IN6_ARE_ADDR_EQUAL(a,b) \
|
||||
__ARE_4_EQUAL((const uint32_t *)(a), (const uint32_t *)(b))
|
||||
|
||||
#define IN_CLASSA(a) ((((in_addr_t)(a)) & 0x80000000) == 0)
|
||||
#define IN_CLASSA_NET 0xff000000
|
||||
#define IN_CLASSA_NSHIFT 24
|
||||
#define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET)
|
||||
#define IN_CLASSA_MAX 128
|
||||
#define IN_CLASSB(a) ((((in_addr_t)(a)) & 0xc0000000) == 0x80000000)
|
||||
#define IN_CLASSB_NET 0xffff0000
|
||||
#define IN_CLASSB_NSHIFT 16
|
||||
#define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET)
|
||||
#define IN_CLASSB_MAX 65536
|
||||
#define IN_CLASSC(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xc0000000)
|
||||
#define IN_CLASSC_NET 0xffffff00
|
||||
#define IN_CLASSC_NSHIFT 8
|
||||
#define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET)
|
||||
#define IN_CLASSD(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xe0000000)
|
||||
#define IN_MULTICAST(a) IN_CLASSD(a)
|
||||
#define IN_EXPERIMENTAL(a) ((((in_addr_t)(a)) & 0xe0000000) == 0xe0000000)
|
||||
#define IN_BADCLASS(a) ((((in_addr_t)(a)) & 0xf0000000) == 0xf0000000)
|
||||
// } from musl
|
||||
|
||||
#endif // _BITS_NETINET_IN_H
|
||||
@@ -0,0 +1,86 @@
|
||||
#ifndef _RELIBC_BITS_PTHREAD_H
|
||||
#define _RELIBC_BITS_PTHREAD_H
|
||||
|
||||
#include <bits/sched.h>
|
||||
#define PTHREAD_COND_INITIALIZER ((pthread_cond_t){0})
|
||||
#define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t){0})
|
||||
#define PTHREAD_ONCE_INIT ((pthread_once_t){0})
|
||||
#define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t){0})
|
||||
|
||||
#define pthread_cleanup_push(ROUTINE, ARG) do { \
|
||||
struct { \
|
||||
void (*routine)(void *); \
|
||||
void *arg; \
|
||||
void *prev; \
|
||||
} __relibc_internal_pthread_ll_entry = { \
|
||||
.routine = (void (*)(void *))(ROUTINE), \
|
||||
.arg = (void *)(ARG), \
|
||||
}; \
|
||||
__relibc_internal_pthread_cleanup_push(&__relibc_internal_pthread_ll_entry);
|
||||
|
||||
#define pthread_cleanup_pop(EXECUTE) \
|
||||
__relibc_internal_pthread_cleanup_pop((EXECUTE)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[32];
|
||||
size_t __relibc_internal_align;
|
||||
} pthread_attr_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[1];
|
||||
unsigned char __relibc_internal_align;
|
||||
} pthread_rwlockattr_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[4];
|
||||
int __relibc_internal_align;
|
||||
} pthread_rwlock_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[24];
|
||||
int __relibc_internal_align;
|
||||
} pthread_barrier_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[4];
|
||||
int __relibc_internal_align;
|
||||
} pthread_barrierattr_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[12];
|
||||
int __relibc_internal_align;
|
||||
} pthread_mutex_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[20];
|
||||
int __relibc_internal_align;
|
||||
} pthread_mutexattr_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[8];
|
||||
int __relibc_internal_align;
|
||||
} pthread_condattr_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[8];
|
||||
int __relibc_internal_align;
|
||||
} pthread_cond_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[4];
|
||||
int __relibc_internal_align;
|
||||
} pthread_spinlock_t;
|
||||
|
||||
typedef union {
|
||||
unsigned char __relibc_internal_size[4];
|
||||
int __relibc_internal_align;
|
||||
} pthread_once_t;
|
||||
|
||||
typedef void *pthread_t;
|
||||
|
||||
typedef unsigned long pthread_key_t;
|
||||
|
||||
#endif /* _RELIBC_BITS_PTHREAD_H */
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef _RELIBC_BITS_SCHED_H
|
||||
#define _RELIBC_BITS_SCHED_H
|
||||
|
||||
#endif /* _RELIBC_BITS_SCHED_H */
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _BITS_SIGNAL_H
|
||||
#define _BITS_SIGNAL_H
|
||||
|
||||
#define SIG_DFL ((void (*)(int))0)
|
||||
#define SIG_IGN ((void (*)(int))1)
|
||||
#define SIG_ERR ((void (*)(int))-1)
|
||||
|
||||
typedef struct siginfo siginfo_t;
|
||||
typedef unsigned long long sigset_t;
|
||||
typedef struct ucontext ucontext_t;
|
||||
typedef struct mcontext mcontext_t;
|
||||
|
||||
struct sigaction {
|
||||
union {
|
||||
void (*sa_handler)(int);
|
||||
void (*sa_sigaction)(int, siginfo_t *, void *);
|
||||
};
|
||||
unsigned long sa_flags;
|
||||
void (*sa_restorer)(void);
|
||||
sigset_t sa_mask;
|
||||
};
|
||||
|
||||
#endif // _BITS_SIGNAL_H
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef _BITS_STDIO_H
|
||||
#define _BITS_STDIO_H
|
||||
|
||||
// XXX: this is only here because cbindgen can't handle string constants
|
||||
#define P_tmpdir "/tmp"
|
||||
|
||||
typedef struct FILE FILE;
|
||||
|
||||
// A typedef doesn't suffice, because libgmp uses this definition to check if
|
||||
// STDIO was loaded.
|
||||
#define FILE FILE
|
||||
|
||||
#endif /* _BITS_STDIO_H */
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef _BITS_STDLIB_H
|
||||
#define _BITS_STDLIB_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
long double strtold(const char *nptr, char **endptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* _BITS_STDLIB_H */
|
||||
@@ -0,0 +1,11 @@
|
||||
// Shamelessly copy-pasted from musl
|
||||
|
||||
#define _IOC(a,b,c,d) ( ((a)<<30) | ((b)<<8) | (c) | ((d)<<16) )
|
||||
#define _IOC_NONE 0U
|
||||
#define _IOC_WRITE 1U
|
||||
#define _IOC_READ 2U
|
||||
|
||||
#define _IO(a,b) _IOC(_IOC_NONE,(a),(b),0)
|
||||
#define _IOW(a,b,c) _IOC(_IOC_WRITE,(a),(b),sizeof(c))
|
||||
#define _IOR(a,b,c) _IOC(_IOC_READ,(a),(b),sizeof(c))
|
||||
#define _IOWR(a,b,c) _IOC(_IOC_READ|_IOC_WRITE,(a),(b),sizeof(c))
|
||||
@@ -0,0 +1,6 @@
|
||||
#ifndef _BITS_SYS_MMAN_H
|
||||
#define _BITS_SYS_MMAN_H
|
||||
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,4 @@
|
||||
#ifndef _BITS_SYS_PTRACE_H
|
||||
#define _BITS_SYS_PTRACE_H
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef _BITS_SYS_RESOURCE_H
|
||||
#define _BITS_SYS_RESOURCE_H
|
||||
|
||||
#define RUSAGE_SELF 0
|
||||
#define RUSAGE_CHILDREN (-1)
|
||||
#define RUSAGE_BOTH (-2)
|
||||
#define RUSAGE_THREAD 1
|
||||
|
||||
#endif /* _BITS_SYS_RESOURCE_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef _BITS_SYS_SELECT_H
|
||||
#define _BITS_SYS_SELECT_H
|
||||
|
||||
#define FD_SETSIZE 1024
|
||||
|
||||
typedef struct fd_set {
|
||||
unsigned long fds_bits[FD_SETSIZE / (8 * sizeof(unsigned long))];
|
||||
} fd_set;
|
||||
|
||||
#define _FD_INDEX(fd) ((fd) / (8 * sizeof(unsigned long)))
|
||||
#define _FD_BITMASK(fd) (1UL << ((fd) & (8 * sizeof(unsigned long) - 1)))
|
||||
|
||||
#define FD_ZERO(set) for (int i = 0; i < sizeof((set)->fds_bits) / sizeof(unsigned long); i += 1) { \
|
||||
(set)->fds_bits[i] = 0; \
|
||||
}
|
||||
|
||||
#define FD_SET(fd, set) ((set)->fds_bits[_FD_INDEX(fd)] |= _FD_BITMASK(fd))
|
||||
#define FD_CLR(fd, set) ((set)->fds_bits[_FD_INDEX(fd)] &= ~(_FD_BITMASK(fd)))
|
||||
|
||||
#define FD_ISSET(fd, set) (((set)->fds_bits[_FD_INDEX(fd)] & _FD_BITMASK(fd)) == _FD_BITMASK(fd))
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef _BITS_SYS_SOCKET_H
|
||||
#define _BITS_SYS_SOCKET_H
|
||||
|
||||
struct sockaddr_storage {
|
||||
sa_family_t ss_family;
|
||||
char __ss_padding[128-sizeof(long)-sizeof(sa_family_t)];
|
||||
unsigned long __ss_align;
|
||||
};
|
||||
|
||||
struct ucred {
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
};
|
||||
|
||||
#endif // _BITS_SYS_SOCKET_H
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef _BITS_STAT_H
|
||||
#define _BITS_STAT_H
|
||||
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
|
||||
#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
|
||||
#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
|
||||
#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFIFO)
|
||||
#define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK)
|
||||
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||
|
||||
#define st_atime st_atim.tv_sec
|
||||
#define st_mtime st_mtim.tv_sec
|
||||
#define st_ctime st_ctim.tv_sec
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef _BITS_SYS_TIME
|
||||
#define _BITS_SYS_TIME
|
||||
|
||||
#define timeradd(x,y,res) (void) (\
|
||||
(res)->tv_sec = (x)->tv_sec + (y)->tv_sec + (((x)->tv_usec + (y)->tv_usec) / 1000000), \
|
||||
(res)->tv_usec = ((x)->tv_usec + (y)->tv_usec) % 1000000 \
|
||||
)
|
||||
#define timersub(x,y,res) (void) ( \
|
||||
(res)->tv_sec = (x)->tv_sec - (y)->tv_sec, \
|
||||
(res)->tv_usec = ((x)->tv_usec - (y)->tv_usec), \
|
||||
((res)->tv_usec < 0) && ((res)->tv_sec -= 1, (res)->tv_usec += 1000000) \
|
||||
)
|
||||
#define timerclear(t) (void) ( \
|
||||
(t)->tv_sec = 0, \
|
||||
(t)->tv_usec = 0 \
|
||||
)
|
||||
#define timerisset(t) ((t)->tv_sec || (t)->tv_usec)
|
||||
#define timercmp(x,y,op) ((x)->tv_sec == (y)->tv_sec ? \
|
||||
(x)->tv_usec op (y)->tv_usec \
|
||||
: \
|
||||
(x)->tv_sec op (y)->tv_sec)
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
#ifndef _BITS_SYS_WAIT_H
|
||||
#define _BITS_SYS_WAIT_H
|
||||
|
||||
#define WEXITSTATUS(s) (((s) >> 8) & 0xff)
|
||||
#define WTERMSIG(s) (((s) & 0x7f) != 0)
|
||||
#define WSTOPSIG(s) WEXITSTATUS(s)
|
||||
#define WCOREDUMP(s) (((s) & 0x80) != 0)
|
||||
#define WIFEXITED(s) (((s) & 0x7f) == 0)
|
||||
#define WIFSTOPPED(s) (((s) & 0xff) == 0x7f)
|
||||
#define WIFSIGNALED(s) (((((s) & 0x7f) + 1U) & 0x7f) >= 2) // Ends with 1111111 or 10000000
|
||||
#define WIFCONTINUED(s) ((s) == 0xffff)
|
||||
|
||||
#endif /* _BITS_SYS_WAIT_H */
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef _BITS_UNISTD_H
|
||||
#define _BITS_UNISTD_H
|
||||
|
||||
#define _POSIX_VERSION 200809L
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef _BITS_WCHAR_H
|
||||
#define _BITS_WCHAR_H
|
||||
|
||||
// int32_t, uint32_t, WCHAR_MIN, WCHAR_MAX
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef _WCHAR_T
|
||||
#define _WCHAR_T
|
||||
#ifndef __WCHAR_TYPE__
|
||||
#define __WCHAR_TYPE__ int32_t
|
||||
#endif
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
#endif // _WCHAR_T
|
||||
|
||||
#ifndef _WINT_T
|
||||
#define _WINT_T
|
||||
#ifndef __WINT_TYPE__
|
||||
#define __WINT_TYPE__ uint32_t
|
||||
#endif
|
||||
typedef __WINT_TYPE__ wint_t;
|
||||
#endif // _WINT_T
|
||||
|
||||
// NULL, size_t, must come after wchar_t and wint_t
|
||||
#define __need_size_t
|
||||
#define __need_NULL
|
||||
#include <stddef.h>
|
||||
|
||||
#define WEOF (0xffffffffu)
|
||||
|
||||
#endif /* _BITS_WCHAR_H */
|
||||
@@ -0,0 +1,102 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Berkeley Software Design, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)cdefs.h 8.8 (Berkeley) 1/9/95
|
||||
* $FreeBSD: src/sys/sys/cdefs.h,v 1.114 2011/02/18 21:44:53 nwhitehorn Exp $
|
||||
*/
|
||||
|
||||
/* Do not redefine macros if the system provides them in sys/cdefs.h.
|
||||
* The two macros correspond to different platforms. */
|
||||
#ifndef _BSD_CDEFS_H_
|
||||
#define _BSD_CDEFS_H_
|
||||
|
||||
/*
|
||||
* This code has been put in place to help reduce the addition of
|
||||
* compiler specific defines in FreeBSD code. It helps to aid in
|
||||
* having a compiler-agnostic source tree.
|
||||
*/
|
||||
|
||||
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
|
||||
|
||||
#if __GNUC__ >= 3 || defined(__INTEL_COMPILER)
|
||||
#define __GNUCLIKE_ASM 3
|
||||
#else
|
||||
#define __GNUCLIKE_ASM 2
|
||||
#endif
|
||||
|
||||
#define __CC_SUPPORTS___INLINE__ 1
|
||||
|
||||
#endif /* __GNUC__ || __INTEL_COMPILER */
|
||||
|
||||
#if defined(__STDC__) || defined(__cplusplus)
|
||||
|
||||
#define __volatile volatile
|
||||
#if defined(__cplusplus)
|
||||
#define __inline inline /* convert to C++ keyword */
|
||||
#else
|
||||
#if !defined(__CC_SUPPORTS___INLINE)
|
||||
#define __inline /* delete GCC keyword */
|
||||
#endif /* ! __CC_SUPPORTS___INLINE */
|
||||
#endif /* !__cplusplus */
|
||||
|
||||
#else /* !(__STDC__ || __cplusplus) */
|
||||
|
||||
#if !defined(__CC_SUPPORTS___INLINE)
|
||||
#define __inline
|
||||
#define __volatile
|
||||
#endif /* !__CC_SUPPORTS___INLINE */
|
||||
#endif /* !(__STDC__ || __cplusplus) */
|
||||
|
||||
/*
|
||||
* Macro to test if we're using a specific version of gcc or later.
|
||||
*/
|
||||
#ifndef __GNUC_PREREQ__
|
||||
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
|
||||
#define __GNUC_PREREQ__(ma, mi) \
|
||||
(__GNUC__ > (ma) || __GNUC__ == (ma) && __GNUC_MINOR__ >= (mi))
|
||||
#else
|
||||
#define __GNUC_PREREQ__(ma, mi) 0
|
||||
#endif
|
||||
#endif /* __GNUC_PREREQ__ */
|
||||
|
||||
/*
|
||||
* Compiler-dependent macro to help declare pure (no side effects) functions.
|
||||
* It is null except for versions of gcc that are known to support the features
|
||||
* properly (old versions of gcc-2 supported the dead and pure features
|
||||
* in a different (wrong) way), and for icc. If we do not provide an implementation
|
||||
* for a given compiler, let the compile fail if it is told to use
|
||||
* a feature that we cannot live without.
|
||||
*/
|
||||
#if !defined(__pure2) && (__GNUC_PREREQ__(2, 7) || defined(__INTEL_COMPILER))
|
||||
#define __pure2 __attribute__((__const__))
|
||||
#endif
|
||||
|
||||
#endif /* !_BSD_CDEFS_H_ */
|
||||
@@ -0,0 +1,85 @@
|
||||
// <algorithm> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2023 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 <bits/stl_algobase.h>
|
||||
#include <bits/stl_algo.h>
|
||||
#if __cplusplus > 201703L
|
||||
# include <bits/ranges_algo.h>
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 201402L && _GLIBCXX_HOSTED
|
||||
// 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 && HOSTED
|
||||
|
||||
#ifdef _GLIBCXX_PARALLEL
|
||||
# include <parallel/algorithm>
|
||||
#endif
|
||||
|
||||
#endif /* _GLIBCXX_ALGORITHM */
|
||||
@@ -0,0 +1,656 @@
|
||||
// <any> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2014-2023 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 <initializer_list>
|
||||
#include <typeinfo>
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <bits/utility.h> // in_place_type_t
|
||||
|
||||
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 `any` object's state is either empty or it stores a contained object
|
||||
* of CopyConstructible type.
|
||||
*
|
||||
* @since C++17
|
||||
*/
|
||||
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_v<_VTp>
|
||||
&& !__is_in_place_type_v<_VTp>, 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)...);
|
||||
return *any::_Manager<_VTp>::_S_access(_M_storage);
|
||||
}
|
||||
|
||||
/// 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)...);
|
||||
return *any::_Manager<_VTp>::_S_access(_M_storage);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
/// @cond undocumented
|
||||
template<typename _Tp>
|
||||
static constexpr bool __is_valid_cast()
|
||||
{ return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
|
||||
/// @endcond
|
||||
|
||||
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;
|
||||
|
||||
/// @cond undocumented
|
||||
template<typename _Tp>
|
||||
friend void* __any_caster(const any* __any);
|
||||
/// @endcond
|
||||
|
||||
// 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)...);
|
||||
}
|
||||
|
||||
static _Tp*
|
||||
_S_access(const _Storage& __storage)
|
||||
{
|
||||
// The contained object is in __storage._M_buffer
|
||||
const void* __addr = &__storage._M_buffer;
|
||||
return static_cast<_Tp*>(const_cast<void*>(__addr));
|
||||
}
|
||||
};
|
||||
|
||||
// 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)...);
|
||||
}
|
||||
static _Tp*
|
||||
_S_access(const _Storage& __storage)
|
||||
{
|
||||
// The contained object is in *__storage._M_ptr
|
||||
return static_cast<_Tp*>(__storage._M_ptr);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/// Exchange the states of two @c any objects.
|
||||
inline void swap(any& __x, any& __y) noexcept { __x.swap(__y); }
|
||||
|
||||
/// Create an `any` holding a `_Tp` constructed from `__args...`.
|
||||
template <typename _Tp, typename... _Args>
|
||||
inline
|
||||
enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>, _Args...>, any>
|
||||
make_any(_Args&&... __args)
|
||||
{
|
||||
return any(in_place_type<_Tp>, std::forward<_Args>(__args)...);
|
||||
}
|
||||
|
||||
/// Create an `any` holding a `_Tp` constructed from `__il` and `__args...`.
|
||||
template <typename _Tp, typename _Up, typename... _Args>
|
||||
inline
|
||||
enable_if_t<is_constructible_v<any, in_place_type_t<_Tp>,
|
||||
initializer_list<_Up>&, _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
|
||||
)
|
||||
{
|
||||
return any::_Manager<_Up>::_S_access(__any->_M_storage);
|
||||
}
|
||||
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
|
||||
@@ -0,0 +1,489 @@
|
||||
// <array> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007-2023 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 <compare>
|
||||
#include <initializer_list>
|
||||
|
||||
#include <type_traits>
|
||||
#include <bits/functexcept.h>
|
||||
#include <bits/stl_algobase.h>
|
||||
#include <bits/range_access.h> // std::begin, std::end etc.
|
||||
#include <bits/utility.h> // std::index_sequence, std::tuple_size
|
||||
#include <debug/assertions.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
template<typename _Tp, size_t _Nm>
|
||||
struct __array_traits
|
||||
{
|
||||
using _Type = _Tp[_Nm];
|
||||
using _Is_swappable = __is_swappable<_Tp>;
|
||||
using _Is_nothrow_swappable = __is_nothrow_swappable<_Tp>;
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __array_traits<_Tp, 0>
|
||||
{
|
||||
// Empty type used instead of _Tp[0] for std::array<_Tp, 0>.
|
||||
struct _Type
|
||||
{
|
||||
// Indexing is undefined.
|
||||
__attribute__((__always_inline__,__noreturn__))
|
||||
_Tp& operator[](size_t) const noexcept { __builtin_trap(); }
|
||||
|
||||
// Conversion to a pointer produces a null pointer.
|
||||
__attribute__((__always_inline__))
|
||||
constexpr explicit operator _Tp*() const noexcept { return nullptr; }
|
||||
};
|
||||
|
||||
using _Is_swappable = true_type;
|
||||
using _Is_nothrow_swappable = true_type;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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.
|
||||
typename __array_traits<_Tp, _Nm>::_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(__array_traits<_Tp, _Nm>::_Is_nothrow_swappable::value)
|
||||
{ std::swap_ranges(begin(), end(), __other.begin()); }
|
||||
|
||||
// Iterators.
|
||||
[[__gnu__::__const__, __nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR iterator
|
||||
begin() noexcept
|
||||
{ return iterator(data()); }
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR const_iterator
|
||||
begin() const noexcept
|
||||
{ return const_iterator(data()); }
|
||||
|
||||
[[__gnu__::__const__, __nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR iterator
|
||||
end() noexcept
|
||||
{ return iterator(data() + _Nm); }
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR const_iterator
|
||||
end() const noexcept
|
||||
{ return const_iterator(data() + _Nm); }
|
||||
|
||||
[[__gnu__::__const__, __nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR reverse_iterator
|
||||
rbegin() noexcept
|
||||
{ return reverse_iterator(end()); }
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR const_reverse_iterator
|
||||
rbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
[[__gnu__::__const__, __nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR reverse_iterator
|
||||
rend() noexcept
|
||||
{ return reverse_iterator(begin()); }
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR const_reverse_iterator
|
||||
rend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR const_iterator
|
||||
cbegin() const noexcept
|
||||
{ return const_iterator(data()); }
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR const_iterator
|
||||
cend() const noexcept
|
||||
{ return const_iterator(data() + _Nm); }
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR const_reverse_iterator
|
||||
crbegin() const noexcept
|
||||
{ return const_reverse_iterator(end()); }
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR const_reverse_iterator
|
||||
crend() const noexcept
|
||||
{ return const_reverse_iterator(begin()); }
|
||||
|
||||
// Capacity.
|
||||
[[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
|
||||
constexpr size_type
|
||||
size() const noexcept { return _Nm; }
|
||||
|
||||
[[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
|
||||
constexpr size_type
|
||||
max_size() const noexcept { return _Nm; }
|
||||
|
||||
[[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
|
||||
constexpr bool
|
||||
empty() const noexcept { return size() == 0; }
|
||||
|
||||
// Element access.
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR reference
|
||||
operator[](size_type __n) noexcept
|
||||
{
|
||||
__glibcxx_requires_subscript(__n);
|
||||
return _M_elems[__n];
|
||||
}
|
||||
|
||||
[[__nodiscard__]]
|
||||
constexpr const_reference
|
||||
operator[](size_type __n) const noexcept
|
||||
{
|
||||
#if __cplusplus >= 201402L
|
||||
__glibcxx_requires_subscript(__n);
|
||||
#endif
|
||||
return _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 _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 ? _M_elems[__n]
|
||||
: (std::__throw_out_of_range_fmt(__N("array::at: __n (which is %zu) "
|
||||
">= _Nm (which is %zu)"),
|
||||
__n, _Nm),
|
||||
_M_elems[__n]);
|
||||
}
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR reference
|
||||
front() noexcept
|
||||
{
|
||||
__glibcxx_requires_nonempty();
|
||||
return _M_elems[(size_type)0];
|
||||
}
|
||||
|
||||
[[__nodiscard__]]
|
||||
constexpr const_reference
|
||||
front() const noexcept
|
||||
{
|
||||
#if __cplusplus >= 201402L
|
||||
__glibcxx_requires_nonempty();
|
||||
#endif
|
||||
return _M_elems[(size_type)0];
|
||||
}
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR reference
|
||||
back() noexcept
|
||||
{
|
||||
__glibcxx_requires_nonempty();
|
||||
return _M_elems[_Nm - 1];
|
||||
}
|
||||
|
||||
[[__nodiscard__]]
|
||||
constexpr const_reference
|
||||
back() const noexcept
|
||||
{
|
||||
#if __cplusplus >= 201402L
|
||||
__glibcxx_requires_nonempty();
|
||||
#endif
|
||||
return _M_elems[_Nm - 1];
|
||||
}
|
||||
|
||||
[[__nodiscard__, __gnu__::__const__, __gnu__::__always_inline__]]
|
||||
_GLIBCXX17_CONSTEXPR pointer
|
||||
data() noexcept
|
||||
{ return static_cast<pointer>(_M_elems); }
|
||||
|
||||
[[__nodiscard__]]
|
||||
_GLIBCXX17_CONSTEXPR const_pointer
|
||||
data() const noexcept
|
||||
{ return static_cast<const_pointer>(_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>
|
||||
[[__nodiscard__]]
|
||||
_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>
|
||||
[[nodiscard]]
|
||||
constexpr __detail::__synth3way_t<_Tp>
|
||||
operator<=>(const array<_Tp, _Nm>& __a, const array<_Tp, _Nm>& __b)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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>
|
||||
[[__nodiscard__]]
|
||||
_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>
|
||||
[[__nodiscard__]]
|
||||
_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>
|
||||
[[__nodiscard__]]
|
||||
_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>
|
||||
[[__nodiscard__]]
|
||||
_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>
|
||||
[[__nodiscard__]]
|
||||
_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
|
||||
__enable_if_t<__array_traits<_Tp, _Nm>::_Is_swappable::value>
|
||||
#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>
|
||||
__enable_if_t<!__array_traits<_Tp, _Nm>::_Is_swappable::value>
|
||||
swap(array<_Tp, _Nm>&, array<_Tp, _Nm>&) = delete;
|
||||
#endif
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
[[__nodiscard__]]
|
||||
constexpr _Tp&
|
||||
get(array<_Tp, _Nm>& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "array index is within bounds");
|
||||
return __arr._M_elems[_Int];
|
||||
}
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
[[__nodiscard__]]
|
||||
constexpr _Tp&&
|
||||
get(array<_Tp, _Nm>&& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "array index is within bounds");
|
||||
return std::move(std::get<_Int>(__arr));
|
||||
}
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
[[__nodiscard__]]
|
||||
constexpr const _Tp&
|
||||
get(const array<_Tp, _Nm>& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "array index is within bounds");
|
||||
return __arr._M_elems[_Int];
|
||||
}
|
||||
|
||||
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
|
||||
[[__nodiscard__]]
|
||||
constexpr const _Tp&&
|
||||
get(const array<_Tp, _Nm>&& __arr) noexcept
|
||||
{
|
||||
static_assert(_Int < _Nm, "array index is within bounds");
|
||||
return std::move(std::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>
|
||||
[[nodiscard]]
|
||||
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 __to_array(__a, make_index_sequence<_Nm>{});
|
||||
__builtin_unreachable(); // FIXME: see PR c++/91388
|
||||
}
|
||||
|
||||
template<typename _Tp, size_t _Nm>
|
||||
[[nodiscard]]
|
||||
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 __to_array<1>(__a, make_index_sequence<_Nm>{});
|
||||
__builtin_unreachable(); // FIXME: see PR c++/91388
|
||||
}
|
||||
#endif // C++20
|
||||
|
||||
// Tuple interface to class template array.
|
||||
|
||||
/// Partial specialization for std::array
|
||||
template<typename _Tp, size_t _Nm>
|
||||
struct tuple_size<array<_Tp, _Nm>>
|
||||
: public integral_constant<size_t, _Nm> { };
|
||||
|
||||
/// Partial specialization for std::array
|
||||
template<size_t _Ind, typename _Tp, size_t _Nm>
|
||||
struct tuple_element<_Ind, array<_Tp, _Nm>>
|
||||
{
|
||||
static_assert(_Ind < _Nm, "array index is in range");
|
||||
using type = _Tp;
|
||||
};
|
||||
|
||||
#if __cplusplus >= 201703L
|
||||
template<typename _Tp, size_t _Nm>
|
||||
inline constexpr size_t tuple_size_v<array<_Tp, _Nm>> = _Nm;
|
||||
|
||||
template<typename _Tp, size_t _Nm>
|
||||
inline constexpr size_t tuple_size_v<const array<_Tp, _Nm>> = _Nm;
|
||||
#endif
|
||||
|
||||
template<typename _Tp, size_t _Nm>
|
||||
struct __is_tuple_like_impl<array<_Tp, _Nm>> : true_type
|
||||
{ };
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
#endif // C++11
|
||||
|
||||
#endif // _GLIBCXX_ARRAY
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,343 @@
|
||||
// auto_ptr implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007-2023 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) { }
|
||||
} _GLIBCXX11_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.
|
||||
*
|
||||
* @headerfile memory
|
||||
* @deprecated Deprecated in C++11, no longer in the standard since C++17.
|
||||
* Use `unique_ptr` instead.
|
||||
*/
|
||||
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()); }
|
||||
} _GLIBCXX11_DEPRECATED_SUGGEST("std::unique_ptr");
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 541. shared_ptr template assignment and void
|
||||
template<>
|
||||
class auto_ptr<void>
|
||||
{
|
||||
public:
|
||||
typedef void element_type;
|
||||
} _GLIBCXX11_DEPRECATED;
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#if _GLIBCXX_HOSTED
|
||||
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)) { }
|
||||
#endif // HOSTED
|
||||
|
||||
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 // C++11
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#endif /* _BACKWARD_AUTO_PTR_H */
|
||||
@@ -0,0 +1,60 @@
|
||||
// Copyright (C) 2001-2023 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
|
||||
@@ -0,0 +1,184 @@
|
||||
// Functor implementations -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2023 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); }
|
||||
} _GLIBCXX11_DEPRECATED_SUGGEST("std::bind");
|
||||
|
||||
/// One of the @link binders binder functors@endlink.
|
||||
template<typename _Operation, typename _Tp>
|
||||
_GLIBCXX11_DEPRECATED_SUGGEST("std::bind")
|
||||
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); }
|
||||
} _GLIBCXX11_DEPRECATED_SUGGEST("std::bind");
|
||||
|
||||
/// One of the @link binders binder functors@endlink.
|
||||
template<typename _Operation, typename _Tp>
|
||||
_GLIBCXX11_DEPRECATED_SUGGEST("std::bind")
|
||||
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 */
|
||||
@@ -0,0 +1,170 @@
|
||||
// 'struct hash' from SGI -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2023 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
|
||||
@@ -0,0 +1,599 @@
|
||||
// Hashing map implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2023 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
|
||||
@@ -0,0 +1,569 @@
|
||||
// Hashing set implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2023 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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,239 @@
|
||||
// Backward-compat support -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2023 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
|
||||
@@ -0,0 +1,266 @@
|
||||
// <barrier> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2020-2023 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/>.
|
||||
|
||||
// This implementation is based on libcxx/include/barrier
|
||||
//===-- barrier.h --------------------------------------------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===---------------------------------------------------------------===//
|
||||
|
||||
/** @file include/barrier
|
||||
* This is a Standard C++ Library header.
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_BARRIER
|
||||
#define _GLIBCXX_BARRIER 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#include <bits/requires_hosted.h> // threading primitive
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
#include <bits/atomic_base.h>
|
||||
#if __cpp_lib_atomic_wait && __cpp_aligned_new
|
||||
#include <bits/std_thread.h>
|
||||
#include <bits/unique_ptr.h>
|
||||
|
||||
#include <array>
|
||||
|
||||
#define __cpp_lib_barrier 201907L
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
struct __empty_completion
|
||||
{
|
||||
_GLIBCXX_ALWAYS_INLINE void
|
||||
operator()() noexcept
|
||||
{ }
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
The default implementation of __tree_barrier is a classic tree barrier.
|
||||
|
||||
It looks different from literature pseudocode for two main reasons:
|
||||
1. Threads that call into std::barrier functions do not provide indices,
|
||||
so a numbering step is added before the actual barrier algorithm,
|
||||
appearing as an N+1 round to the N rounds of the tree barrier.
|
||||
2. A great deal of attention has been paid to avoid cache line thrashing
|
||||
by flattening the tree structure into cache-line sized arrays, that
|
||||
are indexed in an efficient way.
|
||||
|
||||
*/
|
||||
|
||||
enum class __barrier_phase_t : unsigned char { };
|
||||
|
||||
template<typename _CompletionF>
|
||||
class __tree_barrier
|
||||
{
|
||||
using __atomic_phase_ref_t = std::__atomic_ref<__barrier_phase_t>;
|
||||
using __atomic_phase_const_ref_t = std::__atomic_ref<const __barrier_phase_t>;
|
||||
static constexpr auto __phase_alignment =
|
||||
__atomic_phase_ref_t::required_alignment;
|
||||
|
||||
using __tickets_t = std::array<__barrier_phase_t, 64>;
|
||||
struct alignas(64) /* naturally-align the heap state */ __state_t
|
||||
{
|
||||
alignas(__phase_alignment) __tickets_t __tickets;
|
||||
};
|
||||
|
||||
ptrdiff_t _M_expected;
|
||||
unique_ptr<__state_t[]> _M_state;
|
||||
__atomic_base<ptrdiff_t> _M_expected_adjustment;
|
||||
_CompletionF _M_completion;
|
||||
|
||||
alignas(__phase_alignment) __barrier_phase_t _M_phase;
|
||||
|
||||
bool
|
||||
_M_arrive(__barrier_phase_t __old_phase, size_t __current)
|
||||
{
|
||||
const auto __old_phase_val = static_cast<unsigned char>(__old_phase);
|
||||
const auto __half_step =
|
||||
static_cast<__barrier_phase_t>(__old_phase_val + 1);
|
||||
const auto __full_step =
|
||||
static_cast<__barrier_phase_t>(__old_phase_val + 2);
|
||||
|
||||
size_t __current_expected = _M_expected;
|
||||
__current %= ((_M_expected + 1) >> 1);
|
||||
|
||||
for (int __round = 0; ; ++__round)
|
||||
{
|
||||
if (__current_expected <= 1)
|
||||
return true;
|
||||
size_t const __end_node = ((__current_expected + 1) >> 1),
|
||||
__last_node = __end_node - 1;
|
||||
for ( ; ; ++__current)
|
||||
{
|
||||
if (__current == __end_node)
|
||||
__current = 0;
|
||||
auto __expect = __old_phase;
|
||||
__atomic_phase_ref_t __phase(_M_state[__current]
|
||||
.__tickets[__round]);
|
||||
if (__current == __last_node && (__current_expected & 1))
|
||||
{
|
||||
if (__phase.compare_exchange_strong(__expect, __full_step,
|
||||
memory_order_acq_rel))
|
||||
break; // I'm 1 in 1, go to next __round
|
||||
}
|
||||
else if (__phase.compare_exchange_strong(__expect, __half_step,
|
||||
memory_order_acq_rel))
|
||||
{
|
||||
return false; // I'm 1 in 2, done with arrival
|
||||
}
|
||||
else if (__expect == __half_step)
|
||||
{
|
||||
if (__phase.compare_exchange_strong(__expect, __full_step,
|
||||
memory_order_acq_rel))
|
||||
break; // I'm 2 in 2, go to next __round
|
||||
}
|
||||
}
|
||||
__current_expected = __last_node + 1;
|
||||
__current >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
using arrival_token = __barrier_phase_t;
|
||||
|
||||
static constexpr ptrdiff_t
|
||||
max() noexcept
|
||||
{ return __PTRDIFF_MAX__; }
|
||||
|
||||
__tree_barrier(ptrdiff_t __expected, _CompletionF __completion)
|
||||
: _M_expected(__expected), _M_expected_adjustment(0),
|
||||
_M_completion(move(__completion)),
|
||||
_M_phase(static_cast<__barrier_phase_t>(0))
|
||||
{
|
||||
size_t const __count = (_M_expected + 1) >> 1;
|
||||
|
||||
_M_state = std::make_unique<__state_t[]>(__count);
|
||||
}
|
||||
|
||||
[[nodiscard]] arrival_token
|
||||
arrive(ptrdiff_t __update)
|
||||
{
|
||||
std::hash<std::thread::id> __hasher;
|
||||
size_t __current = __hasher(std::this_thread::get_id());
|
||||
__atomic_phase_ref_t __phase(_M_phase);
|
||||
const auto __old_phase = __phase.load(memory_order_relaxed);
|
||||
const auto __cur = static_cast<unsigned char>(__old_phase);
|
||||
for(; __update; --__update)
|
||||
{
|
||||
if(_M_arrive(__old_phase, __current))
|
||||
{
|
||||
_M_completion();
|
||||
_M_expected += _M_expected_adjustment.load(memory_order_relaxed);
|
||||
_M_expected_adjustment.store(0, memory_order_relaxed);
|
||||
auto __new_phase = static_cast<__barrier_phase_t>(__cur + 2);
|
||||
__phase.store(__new_phase, memory_order_release);
|
||||
__phase.notify_all();
|
||||
}
|
||||
}
|
||||
return __old_phase;
|
||||
}
|
||||
|
||||
void
|
||||
wait(arrival_token&& __old_phase) const
|
||||
{
|
||||
__atomic_phase_const_ref_t __phase(_M_phase);
|
||||
auto const __test_fn = [=]
|
||||
{
|
||||
return __phase.load(memory_order_acquire) != __old_phase;
|
||||
};
|
||||
std::__atomic_wait_address(&_M_phase, __test_fn);
|
||||
}
|
||||
|
||||
void
|
||||
arrive_and_drop()
|
||||
{
|
||||
_M_expected_adjustment.fetch_sub(1, memory_order_relaxed);
|
||||
(void)arrive(1);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _CompletionF = __empty_completion>
|
||||
class barrier
|
||||
{
|
||||
// Note, we may introduce a "central" barrier algorithm at some point
|
||||
// for more space constrained targets
|
||||
using __algorithm_t = __tree_barrier<_CompletionF>;
|
||||
__algorithm_t _M_b;
|
||||
|
||||
public:
|
||||
class arrival_token final
|
||||
{
|
||||
public:
|
||||
arrival_token(arrival_token&&) = default;
|
||||
arrival_token& operator=(arrival_token&&) = default;
|
||||
~arrival_token() = default;
|
||||
|
||||
private:
|
||||
friend class barrier;
|
||||
using __token = typename __algorithm_t::arrival_token;
|
||||
explicit arrival_token(__token __tok) noexcept : _M_tok(__tok) { }
|
||||
__token _M_tok;
|
||||
};
|
||||
|
||||
static constexpr ptrdiff_t
|
||||
max() noexcept
|
||||
{ return __algorithm_t::max(); }
|
||||
|
||||
explicit
|
||||
barrier(ptrdiff_t __count, _CompletionF __completion = _CompletionF())
|
||||
: _M_b(__count, std::move(__completion))
|
||||
{ }
|
||||
|
||||
barrier(barrier const&) = delete;
|
||||
barrier& operator=(barrier const&) = delete;
|
||||
|
||||
[[nodiscard]] arrival_token
|
||||
arrive(ptrdiff_t __update = 1)
|
||||
{ return arrival_token{_M_b.arrive(__update)}; }
|
||||
|
||||
void
|
||||
wait(arrival_token&& __phase) const
|
||||
{ _M_b.wait(std::move(__phase._M_tok)); }
|
||||
|
||||
void
|
||||
arrive_and_wait()
|
||||
{ wait(arrive()); }
|
||||
|
||||
void
|
||||
arrive_and_drop()
|
||||
{ _M_b.arrive_and_drop(); }
|
||||
};
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
#endif // __cpp_lib_atomic_wait && __cpp_aligned_new
|
||||
#endif // __cplusplus > 201703L
|
||||
#endif // _GLIBCXX_BARRIER
|
||||
@@ -0,0 +1,482 @@
|
||||
// <bit> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2018-2023 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 || __has_include(<ext/numeric_traits.h>)
|
||||
# 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.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if __cplusplus > 201703l && __has_builtin(__builtin_bit_cast)
|
||||
#define __cpp_lib_bit_cast 201806L
|
||||
|
||||
/// Create a value of type `To` from the bits of `from`.
|
||||
/**
|
||||
* @tparam _To A trivially-copyable type.
|
||||
* @param __from A trivially-copyable object of the same size as `_To`.
|
||||
* @return An object of type `_To`.
|
||||
* @since C++20
|
||||
*/
|
||||
template<typename _To, typename _From>
|
||||
[[nodiscard]]
|
||||
constexpr _To
|
||||
bit_cast(const _From& __from) noexcept
|
||||
#ifdef __cpp_concepts
|
||||
requires (sizeof(_To) == sizeof(_From))
|
||||
&& __is_trivially_copyable(_To) && __is_trivially_copyable(_From)
|
||||
#endif
|
||||
{
|
||||
return __builtin_bit_cast(_To, __from);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 202002L
|
||||
#define __cpp_lib_byteswap 202110L
|
||||
|
||||
/// Reverse order of bytes in the object representation of `value`.
|
||||
/**
|
||||
* @tparam _Tp An integral type.
|
||||
* @param __value An object of integer type.
|
||||
* @return An object of the same type, with the bytes reversed.
|
||||
* @since C++23
|
||||
*/
|
||||
template<typename _Tp>
|
||||
[[nodiscard]]
|
||||
constexpr enable_if_t<is_integral<_Tp>::value, _Tp>
|
||||
byteswap(_Tp __value) noexcept
|
||||
{
|
||||
if constexpr (sizeof(_Tp) == 1)
|
||||
return __value;
|
||||
#if __cpp_if_consteval >= 202106L && __CHAR_BIT__ == 8
|
||||
if !consteval
|
||||
{
|
||||
if constexpr (sizeof(_Tp) == 2)
|
||||
return __builtin_bswap16(__value);
|
||||
if constexpr (sizeof(_Tp) == 4)
|
||||
return __builtin_bswap32(__value);
|
||||
if constexpr (sizeof(_Tp) == 8)
|
||||
return __builtin_bswap64(__value);
|
||||
if constexpr (sizeof(_Tp) == 16)
|
||||
#if __has_builtin(__builtin_bswap128)
|
||||
return __builtin_bswap128(__value);
|
||||
#else
|
||||
return (__builtin_bswap64(__value >> 64)
|
||||
| (static_cast<_Tp>(__builtin_bswap64(__value)) << 64));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// Fallback implementation that handles even __int24 etc.
|
||||
using _Up = typename __make_unsigned<__remove_cv_t<_Tp>>::__type;
|
||||
size_t __diff = __CHAR_BIT__ * (sizeof(_Tp) - 1);
|
||||
_Up __mask1 = static_cast<unsigned char>(~0);
|
||||
_Up __mask2 = __mask1 << __diff;
|
||||
_Up __val = __value;
|
||||
for (size_t __i = 0; __i < sizeof(_Tp) / 2; ++__i)
|
||||
{
|
||||
_Up __byte1 = __val & __mask1;
|
||||
_Up __byte2 = __val & __mask2;
|
||||
__val = (__val ^ __byte1 ^ __byte2
|
||||
^ (__byte1 << __diff) ^ (__byte2 >> __diff));
|
||||
__mask1 <<= __CHAR_BIT__;
|
||||
__mask2 >>= __CHAR_BIT__;
|
||||
__diff -= 2 * __CHAR_BIT__;
|
||||
}
|
||||
return __val;
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @cond undocumented
|
||||
|
||||
template<typename _Tp>
|
||||
constexpr _Tp
|
||||
__rotl(_Tp __x, int __s) noexcept
|
||||
{
|
||||
constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits;
|
||||
if _GLIBCXX17_CONSTEXPR ((_Nd & (_Nd - 1)) == 0)
|
||||
{
|
||||
// Variant for power of two _Nd which the compiler can
|
||||
// easily pattern match.
|
||||
constexpr unsigned __uNd = _Nd;
|
||||
const unsigned __r = __s;
|
||||
return (__x << (__r % __uNd)) | (__x >> ((-__r) % __uNd));
|
||||
}
|
||||
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;
|
||||
if _GLIBCXX17_CONSTEXPR ((_Nd & (_Nd - 1)) == 0)
|
||||
{
|
||||
// Variant for power of two _Nd which the compiler can
|
||||
// easily pattern match.
|
||||
constexpr unsigned __uNd = _Nd;
|
||||
const unsigned __r = __s;
|
||||
return (__x >> (__r % __uNd)) | (__x << ((-__r) % __uNd));
|
||||
}
|
||||
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.
|
||||
if (!std::__is_constant_evaluated())
|
||||
{
|
||||
__glibcxx_assert( __shift_exponent != __int_traits<_Tp>::__digits );
|
||||
}
|
||||
|
||||
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 int
|
||||
__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 undocumented
|
||||
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); }
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 3656. Inconsistent bit operations returning a count
|
||||
/// The smallest integer greater than the base-2 logarithm of `x`.
|
||||
template<typename _Tp>
|
||||
constexpr _If_is_unsigned_integer<_Tp, int>
|
||||
bit_width(_Tp __x) noexcept
|
||||
{ return std::__bit_width(__x); }
|
||||
|
||||
#define __cpp_lib_endian 201907L
|
||||
|
||||
/// Byte order constants
|
||||
/**
|
||||
* The platform endianness can be checked by comparing `std::endian::native`
|
||||
* to one of `std::endian::big` or `std::endian::little`.
|
||||
*
|
||||
* @since C++20
|
||||
*/
|
||||
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
|
||||
@@ -0,0 +1,972 @@
|
||||
// <algorithm> Forward declarations -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007-2023 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);
|
||||
|
||||
_GLIBCXX_BEGIN_INLINE_ABI_NAMESPACE(_V2)
|
||||
|
||||
template<typename _FIter>
|
||||
_GLIBCXX20_CONSTEXPR
|
||||
_FIter
|
||||
rotate(_FIter, _FIter, _FIter);
|
||||
|
||||
_GLIBCXX_END_INLINE_ABI_NAMESPACE(_V2)
|
||||
|
||||
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);
|
||||
|
||||
#if _GLIBCXX_HOSTED
|
||||
template<typename _BIter, typename _Predicate>
|
||||
_BIter
|
||||
stable_partition(_BIter, _BIter, _Predicate);
|
||||
#endif
|
||||
|
||||
#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);
|
||||
|
||||
#if _GLIBCXX_HOSTED
|
||||
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
|
||||
#endif // HOSTED
|
||||
|
||||
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
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
// align implementation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2014-2023 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/align.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{memory}
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_ALIGN_H
|
||||
#define _GLIBCXX_ALIGN_H 1
|
||||
|
||||
#include <bits/c++config.h>
|
||||
|
||||
#include <bit> // std::has_single_bit
|
||||
#include <stdint.h> // uintptr_t
|
||||
#include <debug/assertions.h> // _GLIBCXX_DEBUG_ASSERT
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
/**
|
||||
* @brief Fit aligned storage in buffer.
|
||||
*
|
||||
* This function tries to fit @a __size bytes of storage with alignment
|
||||
* @a __align into the buffer @a __ptr of size @a __space bytes. If such
|
||||
* a buffer fits then @a __ptr is changed to point to the first byte of the
|
||||
* aligned storage and @a __space is reduced by the bytes used for alignment.
|
||||
*
|
||||
* C++11 20.6.5 [ptr.align]
|
||||
*
|
||||
* @param __align A fundamental or extended alignment value.
|
||||
* @param __size Size of the aligned storage required.
|
||||
* @param __ptr Pointer to a buffer of @a __space bytes.
|
||||
* @param __space Size of the buffer pointed to by @a __ptr.
|
||||
* @return the updated pointer if the aligned storage fits, otherwise nullptr.
|
||||
*
|
||||
* @ingroup memory
|
||||
*/
|
||||
inline void*
|
||||
align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
|
||||
{
|
||||
if (__space < __size)
|
||||
return nullptr;
|
||||
const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
|
||||
const auto __aligned = (__intptr - 1u + __align) & -__align;
|
||||
const auto __diff = __aligned - __intptr;
|
||||
if (__diff > (__space - __size))
|
||||
return nullptr;
|
||||
else
|
||||
{
|
||||
__space -= __diff;
|
||||
return __ptr = reinterpret_cast<void*>(__aligned);
|
||||
}
|
||||
}
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
#define __cpp_lib_assume_aligned 201811L
|
||||
/** @brief Inform the compiler that a pointer is aligned.
|
||||
*
|
||||
* @tparam _Align An alignment value (i.e. a power of two)
|
||||
* @tparam _Tp An object type
|
||||
* @param __ptr A pointer that is aligned to _Align
|
||||
*
|
||||
* C++20 20.10.6 [ptr.align]
|
||||
*
|
||||
* @ingroup memory
|
||||
*/
|
||||
template<size_t _Align, class _Tp>
|
||||
[[nodiscard,__gnu__::__always_inline__]]
|
||||
constexpr _Tp*
|
||||
assume_aligned(_Tp* __ptr) noexcept
|
||||
{
|
||||
static_assert(std::has_single_bit(_Align));
|
||||
if (std::is_constant_evaluated())
|
||||
return __ptr;
|
||||
else
|
||||
{
|
||||
// This function is expected to be used in hot code, where
|
||||
// __glibcxx_assert would add unwanted overhead.
|
||||
_GLIBCXX_DEBUG_ASSERT((uintptr_t)__ptr % _Align == 0);
|
||||
return static_cast<_Tp*>(__builtin_assume_aligned(__ptr, _Align));
|
||||
}
|
||||
}
|
||||
#endif // C++2a
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace
|
||||
|
||||
#endif /* _GLIBCXX_ALIGN_H */
|
||||
@@ -0,0 +1,954 @@
|
||||
// Allocator traits -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2011-2023 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/ptr_traits.h>
|
||||
# include <ext/numeric_traits.h>
|
||||
# if _GLIBCXX_HOSTED
|
||||
# include <bits/allocator.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#define __cpp_lib_allocator_traits_is_always_equal 201411L
|
||||
|
||||
/// @cond undocumented
|
||||
struct __allocator_traits_base
|
||||
{
|
||||
template<typename _Tp, typename _Up, typename = void>
|
||||
struct __rebind : __replace_first_arg<_Tp, _Up>
|
||||
{
|
||||
static_assert(is_same<
|
||||
typename __replace_first_arg<_Tp, typename _Tp::value_type>::type,
|
||||
_Tp>::value,
|
||||
"allocator_traits<A>::rebind_alloc<A::value_type> must be A");
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
static_assert(is_same<
|
||||
typename _Tp::template rebind<typename _Tp::value_type>::other,
|
||||
_Tp>::value,
|
||||
"allocator_traits<A>::rebind_alloc<A::value_type> must be A");
|
||||
};
|
||||
|
||||
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 = __type_identity<typename _Tp::is_always_equal>;
|
||||
};
|
||||
|
||||
template<typename _Alloc, typename _Up>
|
||||
using __alloc_rebind
|
||||
= typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
|
||||
/// @endcond
|
||||
|
||||
/**
|
||||
* @brief Uniform interface to all allocator types.
|
||||
* @headerfile memory
|
||||
* @ingroup allocators
|
||||
* @since C++11
|
||||
*/
|
||||
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
|
||||
= typename __detected_or_t<is_empty<_Alloc>, __equal, _Alloc>::type;
|
||||
|
||||
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 _GLIBCXX_HOSTED
|
||||
|
||||
#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)
|
||||
*/
|
||||
[[__nodiscard__,__gnu__::__always_inline__]]
|
||||
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>
|
||||
*/
|
||||
[[__nodiscard__,__gnu__::__always_inline__]]
|
||||
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>
|
||||
*/
|
||||
[[__gnu__::__always_inline__]]
|
||||
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>
|
||||
[[__gnu__::__always_inline__]]
|
||||
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>
|
||||
[[__gnu__::__always_inline__]]
|
||||
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()
|
||||
*/
|
||||
[[__gnu__::__always_inline__]]
|
||||
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
|
||||
*/
|
||||
[[__gnu__::__always_inline__]]
|
||||
static _GLIBCXX20_CONSTEXPR allocator_type
|
||||
select_on_container_copy_construction(const allocator_type& __rhs)
|
||||
{ return __rhs; }
|
||||
};
|
||||
|
||||
/// Explicit specialization for std::allocator<void>.
|
||||
template<>
|
||||
struct allocator_traits<allocator<void>>
|
||||
{
|
||||
/// The allocator type
|
||||
using allocator_type = allocator<void>;
|
||||
|
||||
/// The allocated type
|
||||
using value_type = void;
|
||||
|
||||
/// The allocator's pointer type.
|
||||
using pointer = void*;
|
||||
|
||||
/// The allocator's const pointer type.
|
||||
using const_pointer = const void*;
|
||||
|
||||
/// 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>>;
|
||||
|
||||
/// allocate is ill-formed for allocator<void>
|
||||
static void*
|
||||
allocate(allocator_type&, size_type, const void* = nullptr) = delete;
|
||||
|
||||
/// deallocate is ill-formed for allocator<void>
|
||||
static void
|
||||
deallocate(allocator_type&, void*, size_type) = delete;
|
||||
|
||||
/**
|
||||
* @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>
|
||||
[[__gnu__::__always_inline__]]
|
||||
static _GLIBCXX20_CONSTEXPR void
|
||||
construct(allocator_type&, _Up* __p, _Args&&... __args)
|
||||
noexcept(std::is_nothrow_constructible<_Up, _Args...>::value)
|
||||
{ std::_Construct(__p, std::forward<_Args>(__args)...); }
|
||||
|
||||
/**
|
||||
* @brief Destroy an object of type `_Up`
|
||||
* @param __a An allocator.
|
||||
* @param __p Pointer to the object to destroy
|
||||
*
|
||||
* Invokes the destructor for `*__p`.
|
||||
*/
|
||||
template<typename _Up>
|
||||
[[__gnu__::__always_inline__]]
|
||||
static _GLIBCXX20_CONSTEXPR void
|
||||
destroy(allocator_type&, _Up* __p)
|
||||
noexcept(is_nothrow_destructible<_Up>::value)
|
||||
{ std::_Destroy(__p); }
|
||||
|
||||
/// max_size is ill-formed for allocator<void>
|
||||
static size_type
|
||||
max_size(const allocator_type&) = delete;
|
||||
|
||||
/**
|
||||
* @brief Obtain an allocator to use when copying a container.
|
||||
* @param __rhs An allocator.
|
||||
* @return `__rhs`
|
||||
*/
|
||||
[[__gnu__::__always_inline__]]
|
||||
static _GLIBCXX20_CONSTEXPR allocator_type
|
||||
select_on_container_copy_construction(const allocator_type& __rhs)
|
||||
{ return __rhs; }
|
||||
};
|
||||
#endif
|
||||
|
||||
/// @cond undocumented
|
||||
#if __cplusplus < 201703L
|
||||
template<typename _Alloc>
|
||||
[[__gnu__::__always_inline__]]
|
||||
inline void
|
||||
__do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
|
||||
{ __one = __two; }
|
||||
|
||||
template<typename _Alloc>
|
||||
[[__gnu__::__always_inline__]]
|
||||
inline void
|
||||
__do_alloc_on_copy(_Alloc&, const _Alloc&, false_type)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
template<typename _Alloc>
|
||||
[[__gnu__::__always_inline__]]
|
||||
_GLIBCXX14_CONSTEXPR inline void
|
||||
__alloc_on_copy(_Alloc& __one, const _Alloc& __two)
|
||||
{
|
||||
using __traits = allocator_traits<_Alloc>;
|
||||
using __pocca =
|
||||
typename __traits::propagate_on_container_copy_assignment::type;
|
||||
#if __cplusplus >= 201703L
|
||||
if constexpr (__pocca::value)
|
||||
__one = __two;
|
||||
#else
|
||||
__do_alloc_on_copy(__one, __two, __pocca());
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename _Alloc>
|
||||
[[__gnu__::__always_inline__]]
|
||||
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>
|
||||
[[__gnu__::__always_inline__]]
|
||||
inline void __do_alloc_on_move(_Alloc& __one, _Alloc& __two, true_type)
|
||||
{ __one = std::move(__two); }
|
||||
|
||||
template<typename _Alloc>
|
||||
[[__gnu__::__always_inline__]]
|
||||
inline void __do_alloc_on_move(_Alloc&, _Alloc&, false_type)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
template<typename _Alloc>
|
||||
[[__gnu__::__always_inline__]]
|
||||
_GLIBCXX14_CONSTEXPR inline void
|
||||
__alloc_on_move(_Alloc& __one, _Alloc& __two)
|
||||
{
|
||||
using __traits = allocator_traits<_Alloc>;
|
||||
using __pocma
|
||||
= typename __traits::propagate_on_container_move_assignment::type;
|
||||
#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>
|
||||
[[__gnu__::__always_inline__]]
|
||||
inline void __do_alloc_on_swap(_Alloc& __one, _Alloc& __two, true_type)
|
||||
{
|
||||
using std::swap;
|
||||
swap(__one, __two);
|
||||
}
|
||||
|
||||
template<typename _Alloc>
|
||||
[[__gnu__::__always_inline__]]
|
||||
inline void __do_alloc_on_swap(_Alloc&, _Alloc&, false_type)
|
||||
{ }
|
||||
#endif
|
||||
|
||||
template<typename _Alloc>
|
||||
[[__gnu__::__always_inline__]]
|
||||
_GLIBCXX14_CONSTEXPR inline void
|
||||
__alloc_on_swap(_Alloc& __one, _Alloc& __two)
|
||||
{
|
||||
using __traits = allocator_traits<_Alloc>;
|
||||
using __pocs = typename __traits::propagate_on_container_swap::type;
|
||||
#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
|
||||
{ };
|
||||
|
||||
#if _GLIBCXX_HOSTED
|
||||
// std::allocator<_Tp> just requires CopyConstructible
|
||||
template<typename _Tp>
|
||||
struct __is_copy_insertable<allocator<_Tp>>
|
||||
: is_copy_constructible<_Tp>
|
||||
{ };
|
||||
#endif
|
||||
|
||||
// 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
|
||||
{ };
|
||||
|
||||
#if _GLIBCXX_HOSTED
|
||||
// std::allocator<_Tp> just requires MoveConstructible
|
||||
template<typename _Tp>
|
||||
struct __is_move_insertable<allocator<_Tp>>
|
||||
: is_move_constructible<_Tp>
|
||||
{ };
|
||||
#endif
|
||||
|
||||
// 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;
|
||||
|
||||
#if __cpp_concepts >= 201907L
|
||||
template<typename _Alloc>
|
||||
concept __allocator_like = requires (_Alloc& __a) {
|
||||
typename _Alloc::value_type;
|
||||
__a.deallocate(__a.allocate(1u), 1u);
|
||||
};
|
||||
#endif
|
||||
/// @endcond
|
||||
#endif // C++11
|
||||
|
||||
/// @cond undocumented
|
||||
|
||||
// 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);
|
||||
}
|
||||
};
|
||||
|
||||
#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>
|
||||
{
|
||||
_GLIBCXX20_CONSTEXPR
|
||||
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
|
||||
|
||||
/**
|
||||
* 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>
|
||||
_GLIBCXX20_CONSTEXPR
|
||||
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
|
||||
}
|
||||
|
||||
#if _GLIBCXX_HOSTED
|
||||
template<typename _ForwardIterator, typename _Tp>
|
||||
__attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
|
||||
inline void
|
||||
_Destroy(_ForwardIterator __first, _ForwardIterator __last,
|
||||
allocator<_Tp>&)
|
||||
{
|
||||
std::_Destroy(__first, __last);
|
||||
}
|
||||
#endif
|
||||
/// @endcond
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // _ALLOC_TRAITS_H
|
||||
@@ -0,0 +1,106 @@
|
||||
// Guarded Allocation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2014-2023 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
|
||||
/// @cond undocumented
|
||||
|
||||
/// 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) };
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,294 @@
|
||||
// Allocators -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2023 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 201505L
|
||||
|
||||
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 for C++20,
|
||||
// but trivial for C++98-17, which would be an ABI incompatibility between
|
||||
// different standard dialects. 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.
|
||||
|
||||
/** std::allocator<void> specialization.
|
||||
*
|
||||
* @headerfile memory
|
||||
*/
|
||||
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, allocator_traits does the right thing.
|
||||
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
|
||||
using propagate_on_container_move_assignment = true_type;
|
||||
|
||||
using is_always_equal
|
||||
_GLIBCXX20_DEPRECATED_SUGGEST("std::allocator_traits::is_always_equal")
|
||||
= true_type;
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
// As noted above, these members are present for C++20 to provide the
|
||||
// same API as the primary template, but still trivial as in pre-C++20.
|
||||
allocator() = default;
|
||||
~allocator() = default;
|
||||
|
||||
template<typename _Up>
|
||||
__attribute__((__always_inline__))
|
||||
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.
|
||||
#endif // C++20
|
||||
#endif // C++11
|
||||
};
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*
|
||||
* @headerfile memory
|
||||
*/
|
||||
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
|
||||
using propagate_on_container_move_assignment = true_type;
|
||||
|
||||
using is_always_equal
|
||||
_GLIBCXX20_DEPRECATED_SUGGEST("std::allocator_traits::is_always_equal")
|
||||
= true_type;
|
||||
#endif
|
||||
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 3035. std::allocator's constructors should be constexpr
|
||||
__attribute__((__always_inline__))
|
||||
_GLIBCXX20_CONSTEXPR
|
||||
allocator() _GLIBCXX_NOTHROW { }
|
||||
|
||||
__attribute__((__always_inline__))
|
||||
_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>
|
||||
__attribute__((__always_inline__))
|
||||
_GLIBCXX20_CONSTEXPR
|
||||
allocator(const allocator<_Tp1>&) _GLIBCXX_NOTHROW { }
|
||||
|
||||
__attribute__((__always_inline__))
|
||||
#if __cpp_constexpr_dynamic_alloc
|
||||
constexpr
|
||||
#endif
|
||||
~allocator() _GLIBCXX_NOTHROW { }
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
[[nodiscard,__gnu__::__always_inline__]]
|
||||
constexpr _Tp*
|
||||
allocate(size_t __n)
|
||||
{
|
||||
if (std::__is_constant_evaluated())
|
||||
{
|
||||
if (__builtin_mul_overflow(__n, sizeof(_Tp), &__n))
|
||||
std::__throw_bad_array_new_length();
|
||||
return static_cast<_Tp*>(::operator new(__n));
|
||||
}
|
||||
|
||||
return __allocator_base<_Tp>::allocate(__n, 0);
|
||||
}
|
||||
|
||||
[[__gnu__::__always_inline__]]
|
||||
constexpr void
|
||||
deallocate(_Tp* __p, size_t __n)
|
||||
{
|
||||
if (std::__is_constant_evaluated())
|
||||
{
|
||||
::operator delete(__p);
|
||||
return;
|
||||
}
|
||||
__allocator_base<_Tp>::deallocate(__p, __n);
|
||||
}
|
||||
#endif // C++20
|
||||
|
||||
friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
|
||||
bool
|
||||
operator==(const allocator&, const allocator&) _GLIBCXX_NOTHROW
|
||||
{ return true; }
|
||||
|
||||
#if __cpp_impl_three_way_comparison < 201907L
|
||||
friend __attribute__((__always_inline__)) _GLIBCXX20_CONSTEXPR
|
||||
bool
|
||||
operator!=(const allocator&, const allocator&) _GLIBCXX_NOTHROW
|
||||
{ return false; }
|
||||
#endif
|
||||
|
||||
// Inherit everything else.
|
||||
};
|
||||
|
||||
/** Equality comparison for std::allocator objects
|
||||
*
|
||||
* @return true, for all std::allocator objects.
|
||||
* @relates std::allocator
|
||||
*/
|
||||
template<typename _T1, typename _T2>
|
||||
__attribute__((__always_inline__))
|
||||
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>
|
||||
__attribute__((__always_inline__))
|
||||
inline _GLIBCXX20_CONSTEXPR bool
|
||||
operator!=(const allocator<_T1>&, const allocator<_T2>&)
|
||||
_GLIBCXX_NOTHROW
|
||||
{ return false; }
|
||||
#endif
|
||||
|
||||
/// @cond undocumented
|
||||
|
||||
// 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>&) { }
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
/// @} 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
|
||||
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,360 @@
|
||||
// -*- C++ -*- header.
|
||||
|
||||
// Copyright (C) 2015-2023 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 <atomic>
|
||||
#if ! (defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1)
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#endif
|
||||
#include <bits/chrono.h>
|
||||
|
||||
#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
|
||||
{
|
||||
// __s and __ns are measured against CLOCK_REALTIME. Returns false
|
||||
// iff a timeout occurred.
|
||||
bool
|
||||
_M_futex_wait_until(unsigned *__addr, unsigned __val, bool __has_timeout,
|
||||
chrono::seconds __s, chrono::nanoseconds __ns);
|
||||
|
||||
// __s and __ns are measured against CLOCK_MONOTONIC. Returns
|
||||
// false iff a timeout occurred.
|
||||
bool
|
||||
_M_futex_wait_until_steady(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::steady_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.
|
||||
// __s and __ns are measured against CLOCK_REALTIME.
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
// __s and __ns are measured against CLOCK_MONOTONIC.
|
||||
unsigned
|
||||
_M_load_and_test_until_steady(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_steady((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<std::chrono::system_clock, _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);
|
||||
}
|
||||
|
||||
template<typename _Dur>
|
||||
unsigned
|
||||
_M_load_and_test_until_impl(unsigned __assumed, unsigned __operand,
|
||||
bool __equal, memory_order __mo,
|
||||
const chrono::time_point<std::chrono::steady_clock, _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_steady(__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)
|
||||
{
|
||||
using __dur = typename __clock_t::duration;
|
||||
return _M_load_when_equal_until(__val, __mo,
|
||||
__clock_t::now() + chrono::__detail::ceil<__dur>(__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)
|
||||
{
|
||||
typename _Clock::time_point __c_entry = _Clock::now();
|
||||
do {
|
||||
const __clock_t::time_point __s_entry = __clock_t::now();
|
||||
const auto __delta = __atime - __c_entry;
|
||||
const auto __s_atime = __s_entry +
|
||||
chrono::__detail::ceil<__clock_t::duration>(__delta);
|
||||
if (_M_load_when_equal_until(__val, __mo, __s_atime))
|
||||
return true;
|
||||
__c_entry = _Clock::now();
|
||||
} while (__c_entry < __atime);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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<std::chrono::system_clock, _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;
|
||||
}
|
||||
|
||||
// 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<std::chrono::steady_clock, _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
|
||||
@@ -0,0 +1,66 @@
|
||||
// -*- C++ -*- header.
|
||||
|
||||
// Copyright (C) 2008-2023 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
|
||||
@@ -0,0 +1,452 @@
|
||||
// -*- C++ -*- header.
|
||||
|
||||
// Copyright (C) 2020-2023 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_timed_wait.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{atomic}
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_ATOMIC_TIMED_WAIT_H
|
||||
#define _GLIBCXX_ATOMIC_TIMED_WAIT_H 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#include <bits/atomic_wait.h>
|
||||
|
||||
#if __cpp_lib_atomic_wait
|
||||
#include <bits/functional_hash.h>
|
||||
#include <bits/this_thread_sleep.h>
|
||||
#include <bits/chrono.h>
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
namespace __detail
|
||||
{
|
||||
using __wait_clock_t = chrono::steady_clock;
|
||||
|
||||
template<typename _Clock, typename _Dur>
|
||||
__wait_clock_t::time_point
|
||||
__to_wait_clock(const chrono::time_point<_Clock, _Dur>& __atime) noexcept
|
||||
{
|
||||
const typename _Clock::time_point __c_entry = _Clock::now();
|
||||
const __wait_clock_t::time_point __w_entry = __wait_clock_t::now();
|
||||
const auto __delta = __atime - __c_entry;
|
||||
using __w_dur = typename __wait_clock_t::duration;
|
||||
return __w_entry + chrono::ceil<__w_dur>(__delta);
|
||||
}
|
||||
|
||||
template<typename _Dur>
|
||||
__wait_clock_t::time_point
|
||||
__to_wait_clock(const chrono::time_point<__wait_clock_t,
|
||||
_Dur>& __atime) noexcept
|
||||
{
|
||||
using __w_dur = typename __wait_clock_t::duration;
|
||||
return chrono::ceil<__w_dur>(__atime);
|
||||
}
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
|
||||
#define _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT
|
||||
// returns true if wait ended before timeout
|
||||
template<typename _Dur>
|
||||
bool
|
||||
__platform_wait_until_impl(const __platform_wait_t* __addr,
|
||||
__platform_wait_t __old,
|
||||
const chrono::time_point<__wait_clock_t, _Dur>&
|
||||
__atime) noexcept
|
||||
{
|
||||
auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
|
||||
auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
|
||||
|
||||
struct timespec __rt =
|
||||
{
|
||||
static_cast<std::time_t>(__s.time_since_epoch().count()),
|
||||
static_cast<long>(__ns.count())
|
||||
};
|
||||
|
||||
auto __e = syscall (SYS_futex, __addr,
|
||||
static_cast<int>(__futex_wait_flags::
|
||||
__wait_bitset_private),
|
||||
__old, &__rt, nullptr,
|
||||
static_cast<int>(__futex_wait_flags::
|
||||
__bitset_match_any));
|
||||
|
||||
if (__e)
|
||||
{
|
||||
if (errno == ETIMEDOUT)
|
||||
return false;
|
||||
if (errno != EINTR && errno != EAGAIN)
|
||||
__throw_system_error(errno);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns true if wait ended before timeout
|
||||
template<typename _Clock, typename _Dur>
|
||||
bool
|
||||
__platform_wait_until(const __platform_wait_t* __addr, __platform_wait_t __old,
|
||||
const chrono::time_point<_Clock, _Dur>& __atime)
|
||||
{
|
||||
if constexpr (is_same_v<__wait_clock_t, _Clock>)
|
||||
{
|
||||
return __platform_wait_until_impl(__addr, __old, __atime);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!__platform_wait_until_impl(__addr, __old,
|
||||
__to_wait_clock(__atime)))
|
||||
{
|
||||
// We got a timeout when measured against __clock_t but
|
||||
// we need to check against the caller-supplied clock
|
||||
// to tell whether we should return a timeout.
|
||||
if (_Clock::now() < __atime)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// define _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT and implement __platform_wait_until()
|
||||
// if there is a more efficient primitive supported by the platform
|
||||
// (e.g. __ulock_wait())which is better than pthread_cond_clockwait
|
||||
#endif // ! PLATFORM_TIMED_WAIT
|
||||
|
||||
#ifdef _GLIBCXX_HAS_GTHREADS
|
||||
// Returns true if wait ended before timeout.
|
||||
// _Clock must be either steady_clock or system_clock.
|
||||
template<typename _Clock, typename _Dur>
|
||||
bool
|
||||
__cond_wait_until_impl(__condvar& __cv, mutex& __mx,
|
||||
const chrono::time_point<_Clock, _Dur>& __atime)
|
||||
{
|
||||
static_assert(std::__is_one_of<_Clock, chrono::steady_clock,
|
||||
chrono::system_clock>::value);
|
||||
|
||||
auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
|
||||
auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
|
||||
|
||||
__gthread_time_t __ts =
|
||||
{
|
||||
static_cast<std::time_t>(__s.time_since_epoch().count()),
|
||||
static_cast<long>(__ns.count())
|
||||
};
|
||||
|
||||
#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
|
||||
if constexpr (is_same_v<chrono::steady_clock, _Clock>)
|
||||
__cv.wait_until(__mx, CLOCK_MONOTONIC, __ts);
|
||||
else
|
||||
#endif
|
||||
__cv.wait_until(__mx, __ts);
|
||||
return _Clock::now() < __atime;
|
||||
}
|
||||
|
||||
// returns true if wait ended before timeout
|
||||
template<typename _Clock, typename _Dur>
|
||||
bool
|
||||
__cond_wait_until(__condvar& __cv, mutex& __mx,
|
||||
const chrono::time_point<_Clock, _Dur>& __atime)
|
||||
{
|
||||
#ifdef _GLIBCXX_USE_PTHREAD_COND_CLOCKWAIT
|
||||
if constexpr (is_same_v<_Clock, chrono::steady_clock>)
|
||||
return __detail::__cond_wait_until_impl(__cv, __mx, __atime);
|
||||
else
|
||||
#endif
|
||||
if constexpr (is_same_v<_Clock, chrono::system_clock>)
|
||||
return __detail::__cond_wait_until_impl(__cv, __mx, __atime);
|
||||
else
|
||||
{
|
||||
if (__cond_wait_until_impl(__cv, __mx,
|
||||
__to_wait_clock(__atime)))
|
||||
{
|
||||
// We got a timeout when measured against __clock_t but
|
||||
// we need to check against the caller-supplied clock
|
||||
// to tell whether we should return a timeout.
|
||||
if (_Clock::now() < __atime)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif // _GLIBCXX_HAS_GTHREADS
|
||||
|
||||
struct __timed_waiter_pool : __waiter_pool_base
|
||||
{
|
||||
// returns true if wait ended before timeout
|
||||
template<typename _Clock, typename _Dur>
|
||||
bool
|
||||
_M_do_wait_until(__platform_wait_t* __addr, __platform_wait_t __old,
|
||||
const chrono::time_point<_Clock, _Dur>& __atime)
|
||||
{
|
||||
#ifdef _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT
|
||||
return __platform_wait_until(__addr, __old, __atime);
|
||||
#else
|
||||
__platform_wait_t __val;
|
||||
__atomic_load(__addr, &__val, __ATOMIC_RELAXED);
|
||||
if (__val == __old)
|
||||
{
|
||||
lock_guard<mutex> __l(_M_mtx);
|
||||
return __cond_wait_until(_M_cv, _M_mtx, __atime);
|
||||
}
|
||||
else
|
||||
return true;
|
||||
#endif // _GLIBCXX_HAVE_PLATFORM_TIMED_WAIT
|
||||
}
|
||||
};
|
||||
|
||||
struct __timed_backoff_spin_policy
|
||||
{
|
||||
__wait_clock_t::time_point _M_deadline;
|
||||
__wait_clock_t::time_point _M_t0;
|
||||
|
||||
template<typename _Clock, typename _Dur>
|
||||
__timed_backoff_spin_policy(chrono::time_point<_Clock, _Dur>
|
||||
__deadline = _Clock::time_point::max(),
|
||||
chrono::time_point<_Clock, _Dur>
|
||||
__t0 = _Clock::now()) noexcept
|
||||
: _M_deadline(__to_wait_clock(__deadline))
|
||||
, _M_t0(__to_wait_clock(__t0))
|
||||
{ }
|
||||
|
||||
bool
|
||||
operator()() const noexcept
|
||||
{
|
||||
using namespace literals::chrono_literals;
|
||||
auto __now = __wait_clock_t::now();
|
||||
if (_M_deadline <= __now)
|
||||
return false;
|
||||
|
||||
// FIXME: this_thread::sleep_for not available #ifdef _GLIBCXX_NO_SLEEP
|
||||
|
||||
auto __elapsed = __now - _M_t0;
|
||||
if (__elapsed > 128ms)
|
||||
{
|
||||
this_thread::sleep_for(64ms);
|
||||
}
|
||||
else if (__elapsed > 64us)
|
||||
{
|
||||
this_thread::sleep_for(__elapsed / 2);
|
||||
}
|
||||
else if (__elapsed > 4us)
|
||||
{
|
||||
__thread_yield();
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _EntersWait>
|
||||
struct __timed_waiter : __waiter_base<__timed_waiter_pool>
|
||||
{
|
||||
using __base_type = __waiter_base<__timed_waiter_pool>;
|
||||
|
||||
template<typename _Tp>
|
||||
__timed_waiter(const _Tp* __addr) noexcept
|
||||
: __base_type(__addr)
|
||||
{
|
||||
if constexpr (_EntersWait::value)
|
||||
_M_w._M_enter_wait();
|
||||
}
|
||||
|
||||
~__timed_waiter()
|
||||
{
|
||||
if constexpr (_EntersWait::value)
|
||||
_M_w._M_leave_wait();
|
||||
}
|
||||
|
||||
// returns true if wait ended before timeout
|
||||
template<typename _Tp, typename _ValFn,
|
||||
typename _Clock, typename _Dur>
|
||||
bool
|
||||
_M_do_wait_until_v(_Tp __old, _ValFn __vfn,
|
||||
const chrono::time_point<_Clock, _Dur>&
|
||||
__atime) noexcept
|
||||
{
|
||||
__platform_wait_t __val;
|
||||
if (_M_do_spin(__old, std::move(__vfn), __val,
|
||||
__timed_backoff_spin_policy(__atime)))
|
||||
return true;
|
||||
return __base_type::_M_w._M_do_wait_until(__base_type::_M_addr, __val, __atime);
|
||||
}
|
||||
|
||||
// returns true if wait ended before timeout
|
||||
template<typename _Pred,
|
||||
typename _Clock, typename _Dur>
|
||||
bool
|
||||
_M_do_wait_until(_Pred __pred, __platform_wait_t __val,
|
||||
const chrono::time_point<_Clock, _Dur>&
|
||||
__atime) noexcept
|
||||
{
|
||||
for (auto __now = _Clock::now(); __now < __atime;
|
||||
__now = _Clock::now())
|
||||
{
|
||||
if (__base_type::_M_w._M_do_wait_until(
|
||||
__base_type::_M_addr, __val, __atime)
|
||||
&& __pred())
|
||||
return true;
|
||||
|
||||
if (__base_type::_M_do_spin(__pred, __val,
|
||||
__timed_backoff_spin_policy(__atime, __now)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// returns true if wait ended before timeout
|
||||
template<typename _Pred,
|
||||
typename _Clock, typename _Dur>
|
||||
bool
|
||||
_M_do_wait_until(_Pred __pred,
|
||||
const chrono::time_point<_Clock, _Dur>&
|
||||
__atime) noexcept
|
||||
{
|
||||
__platform_wait_t __val;
|
||||
if (__base_type::_M_do_spin(__pred, __val,
|
||||
__timed_backoff_spin_policy(__atime)))
|
||||
return true;
|
||||
return _M_do_wait_until(__pred, __val, __atime);
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _ValFn,
|
||||
typename _Rep, typename _Period>
|
||||
bool
|
||||
_M_do_wait_for_v(_Tp __old, _ValFn __vfn,
|
||||
const chrono::duration<_Rep, _Period>&
|
||||
__rtime) noexcept
|
||||
{
|
||||
__platform_wait_t __val;
|
||||
if (_M_do_spin_v(__old, std::move(__vfn), __val))
|
||||
return true;
|
||||
|
||||
if (!__rtime.count())
|
||||
return false; // no rtime supplied, and spin did not acquire
|
||||
|
||||
auto __reltime = chrono::ceil<__wait_clock_t::duration>(__rtime);
|
||||
|
||||
return __base_type::_M_w._M_do_wait_until(
|
||||
__base_type::_M_addr,
|
||||
__val,
|
||||
chrono::steady_clock::now() + __reltime);
|
||||
}
|
||||
|
||||
template<typename _Pred,
|
||||
typename _Rep, typename _Period>
|
||||
bool
|
||||
_M_do_wait_for(_Pred __pred,
|
||||
const chrono::duration<_Rep, _Period>& __rtime) noexcept
|
||||
{
|
||||
__platform_wait_t __val;
|
||||
if (__base_type::_M_do_spin(__pred, __val))
|
||||
return true;
|
||||
|
||||
if (!__rtime.count())
|
||||
return false; // no rtime supplied, and spin did not acquire
|
||||
|
||||
auto __reltime = chrono::ceil<__wait_clock_t::duration>(__rtime);
|
||||
|
||||
return _M_do_wait_until(__pred, __val,
|
||||
chrono::steady_clock::now() + __reltime);
|
||||
}
|
||||
};
|
||||
|
||||
using __enters_timed_wait = __timed_waiter<std::true_type>;
|
||||
using __bare_timed_wait = __timed_waiter<std::false_type>;
|
||||
} // namespace __detail
|
||||
|
||||
// returns true if wait ended before timeout
|
||||
template<typename _Tp, typename _ValFn,
|
||||
typename _Clock, typename _Dur>
|
||||
bool
|
||||
__atomic_wait_address_until_v(const _Tp* __addr, _Tp&& __old, _ValFn&& __vfn,
|
||||
const chrono::time_point<_Clock, _Dur>&
|
||||
__atime) noexcept
|
||||
{
|
||||
__detail::__enters_timed_wait __w{__addr};
|
||||
return __w._M_do_wait_until_v(__old, __vfn, __atime);
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _Pred,
|
||||
typename _Clock, typename _Dur>
|
||||
bool
|
||||
__atomic_wait_address_until(const _Tp* __addr, _Pred __pred,
|
||||
const chrono::time_point<_Clock, _Dur>&
|
||||
__atime) noexcept
|
||||
{
|
||||
__detail::__enters_timed_wait __w{__addr};
|
||||
return __w._M_do_wait_until(__pred, __atime);
|
||||
}
|
||||
|
||||
template<typename _Pred,
|
||||
typename _Clock, typename _Dur>
|
||||
bool
|
||||
__atomic_wait_address_until_bare(const __detail::__platform_wait_t* __addr,
|
||||
_Pred __pred,
|
||||
const chrono::time_point<_Clock, _Dur>&
|
||||
__atime) noexcept
|
||||
{
|
||||
__detail::__bare_timed_wait __w{__addr};
|
||||
return __w._M_do_wait_until(__pred, __atime);
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _ValFn,
|
||||
typename _Rep, typename _Period>
|
||||
bool
|
||||
__atomic_wait_address_for_v(const _Tp* __addr, _Tp&& __old, _ValFn&& __vfn,
|
||||
const chrono::duration<_Rep, _Period>& __rtime) noexcept
|
||||
{
|
||||
__detail::__enters_timed_wait __w{__addr};
|
||||
return __w._M_do_wait_for_v(__old, __vfn, __rtime);
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _Pred,
|
||||
typename _Rep, typename _Period>
|
||||
bool
|
||||
__atomic_wait_address_for(const _Tp* __addr, _Pred __pred,
|
||||
const chrono::duration<_Rep, _Period>& __rtime) noexcept
|
||||
{
|
||||
|
||||
__detail::__enters_timed_wait __w{__addr};
|
||||
return __w._M_do_wait_for(__pred, __rtime);
|
||||
}
|
||||
|
||||
template<typename _Pred,
|
||||
typename _Rep, typename _Period>
|
||||
bool
|
||||
__atomic_wait_address_for_bare(const __detail::__platform_wait_t* __addr,
|
||||
_Pred __pred,
|
||||
const chrono::duration<_Rep, _Period>& __rtime) noexcept
|
||||
{
|
||||
__detail::__bare_timed_wait __w{__addr};
|
||||
return __w._M_do_wait_for(__pred, __rtime);
|
||||
}
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // __cpp_lib_atomic_wait
|
||||
#endif // _GLIBCXX_ATOMIC_TIMED_WAIT_H
|
||||
@@ -0,0 +1,480 @@
|
||||
// -*- C++ -*- header.
|
||||
|
||||
// Copyright (C) 2020-2023 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_wait.h
|
||||
* This is an internal header file, included by other library headers.
|
||||
* Do not attempt to use it directly. @headername{atomic}
|
||||
*/
|
||||
|
||||
#ifndef _GLIBCXX_ATOMIC_WAIT_H
|
||||
#define _GLIBCXX_ATOMIC_WAIT_H 1
|
||||
|
||||
#pragma GCC system_header
|
||||
|
||||
#include <bits/c++config.h>
|
||||
#if defined _GLIBCXX_HAS_GTHREADS || defined _GLIBCXX_HAVE_LINUX_FUTEX
|
||||
#include <bits/functional_hash.h>
|
||||
#include <bits/gthr.h>
|
||||
#include <ext/numeric_traits.h>
|
||||
|
||||
#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
|
||||
# include <cerrno>
|
||||
# include <climits>
|
||||
# include <unistd.h>
|
||||
# include <syscall.h>
|
||||
# include <bits/functexcept.h>
|
||||
#endif
|
||||
|
||||
# include <bits/std_mutex.h> // std::mutex, std::__condvar
|
||||
|
||||
#define __cpp_lib_atomic_wait 201907L
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
namespace __detail
|
||||
{
|
||||
#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
|
||||
#define _GLIBCXX_HAVE_PLATFORM_WAIT 1
|
||||
using __platform_wait_t = int;
|
||||
inline constexpr size_t __platform_wait_alignment = 4;
|
||||
#else
|
||||
// define _GLIBCX_HAVE_PLATFORM_WAIT and implement __platform_wait()
|
||||
// and __platform_notify() if there is a more efficient primitive supported
|
||||
// by the platform (e.g. __ulock_wait()/__ulock_wake()) which is better than
|
||||
// a mutex/condvar based wait.
|
||||
# if ATOMIC_LONG_LOCK_FREE == 2
|
||||
using __platform_wait_t = unsigned long;
|
||||
# else
|
||||
using __platform_wait_t = unsigned int;
|
||||
# endif
|
||||
inline constexpr size_t __platform_wait_alignment
|
||||
= __alignof__(__platform_wait_t);
|
||||
#endif
|
||||
} // namespace __detail
|
||||
|
||||
template<typename _Tp>
|
||||
inline constexpr bool __platform_wait_uses_type
|
||||
#ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
|
||||
= is_scalar_v<_Tp>
|
||||
&& ((sizeof(_Tp) == sizeof(__detail::__platform_wait_t))
|
||||
&& (alignof(_Tp*) >= __detail::__platform_wait_alignment));
|
||||
#else
|
||||
= false;
|
||||
#endif
|
||||
|
||||
namespace __detail
|
||||
{
|
||||
#ifdef _GLIBCXX_HAVE_LINUX_FUTEX
|
||||
enum class __futex_wait_flags : int
|
||||
{
|
||||
#ifdef _GLIBCXX_HAVE_LINUX_FUTEX_PRIVATE
|
||||
__private_flag = 128,
|
||||
#else
|
||||
__private_flag = 0,
|
||||
#endif
|
||||
__wait = 0,
|
||||
__wake = 1,
|
||||
__wait_bitset = 9,
|
||||
__wake_bitset = 10,
|
||||
__wait_private = __wait | __private_flag,
|
||||
__wake_private = __wake | __private_flag,
|
||||
__wait_bitset_private = __wait_bitset | __private_flag,
|
||||
__wake_bitset_private = __wake_bitset | __private_flag,
|
||||
__bitset_match_any = -1
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
void
|
||||
__platform_wait(const _Tp* __addr, __platform_wait_t __val) noexcept
|
||||
{
|
||||
auto __e = syscall (SYS_futex, static_cast<const void*>(__addr),
|
||||
static_cast<int>(__futex_wait_flags::__wait_private),
|
||||
__val, nullptr);
|
||||
if (!__e || errno == EAGAIN)
|
||||
return;
|
||||
if (errno != EINTR)
|
||||
__throw_system_error(errno);
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
void
|
||||
__platform_notify(const _Tp* __addr, bool __all) noexcept
|
||||
{
|
||||
syscall (SYS_futex, static_cast<const void*>(__addr),
|
||||
static_cast<int>(__futex_wait_flags::__wake_private),
|
||||
__all ? INT_MAX : 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void
|
||||
__thread_yield() noexcept
|
||||
{
|
||||
#if defined _GLIBCXX_HAS_GTHREADS && defined _GLIBCXX_USE_SCHED_YIELD
|
||||
__gthread_yield();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void
|
||||
__thread_relax() noexcept
|
||||
{
|
||||
#if defined __i386__ || defined __x86_64__
|
||||
__builtin_ia32_pause();
|
||||
#else
|
||||
__thread_yield();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline constexpr auto __atomic_spin_count_relax = 12;
|
||||
inline constexpr auto __atomic_spin_count = 16;
|
||||
|
||||
struct __default_spin_policy
|
||||
{
|
||||
bool
|
||||
operator()() const noexcept
|
||||
{ return false; }
|
||||
};
|
||||
|
||||
template<typename _Pred,
|
||||
typename _Spin = __default_spin_policy>
|
||||
bool
|
||||
__atomic_spin(_Pred& __pred, _Spin __spin = _Spin{ }) noexcept
|
||||
{
|
||||
for (auto __i = 0; __i < __atomic_spin_count; ++__i)
|
||||
{
|
||||
if (__pred())
|
||||
return true;
|
||||
|
||||
if (__i < __atomic_spin_count_relax)
|
||||
__detail::__thread_relax();
|
||||
else
|
||||
__detail::__thread_yield();
|
||||
}
|
||||
|
||||
while (__spin())
|
||||
{
|
||||
if (__pred())
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// return true if equal
|
||||
template<typename _Tp>
|
||||
bool __atomic_compare(const _Tp& __a, const _Tp& __b)
|
||||
{
|
||||
// TODO make this do the correct padding bit ignoring comparison
|
||||
return __builtin_memcmp(&__a, &__b, sizeof(_Tp)) == 0;
|
||||
}
|
||||
|
||||
struct __waiter_pool_base
|
||||
{
|
||||
// Don't use std::hardware_destructive_interference_size here because we
|
||||
// don't want the layout of library types to depend on compiler options.
|
||||
static constexpr auto _S_align = 64;
|
||||
|
||||
alignas(_S_align) __platform_wait_t _M_wait = 0;
|
||||
|
||||
#ifndef _GLIBCXX_HAVE_PLATFORM_WAIT
|
||||
mutex _M_mtx;
|
||||
#endif
|
||||
|
||||
alignas(_S_align) __platform_wait_t _M_ver = 0;
|
||||
|
||||
#ifndef _GLIBCXX_HAVE_PLATFORM_WAIT
|
||||
__condvar _M_cv;
|
||||
#endif
|
||||
__waiter_pool_base() = default;
|
||||
|
||||
void
|
||||
_M_enter_wait() noexcept
|
||||
{ __atomic_fetch_add(&_M_wait, 1, __ATOMIC_SEQ_CST); }
|
||||
|
||||
void
|
||||
_M_leave_wait() noexcept
|
||||
{ __atomic_fetch_sub(&_M_wait, 1, __ATOMIC_RELEASE); }
|
||||
|
||||
bool
|
||||
_M_waiting() const noexcept
|
||||
{
|
||||
__platform_wait_t __res;
|
||||
__atomic_load(&_M_wait, &__res, __ATOMIC_SEQ_CST);
|
||||
return __res != 0;
|
||||
}
|
||||
|
||||
void
|
||||
_M_notify(__platform_wait_t* __addr, [[maybe_unused]] bool __all,
|
||||
bool __bare) noexcept
|
||||
{
|
||||
#ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
|
||||
if (__addr == &_M_ver)
|
||||
{
|
||||
__atomic_fetch_add(__addr, 1, __ATOMIC_SEQ_CST);
|
||||
__all = true;
|
||||
}
|
||||
|
||||
if (__bare || _M_waiting())
|
||||
__platform_notify(__addr, __all);
|
||||
#else
|
||||
{
|
||||
lock_guard<mutex> __l(_M_mtx);
|
||||
__atomic_fetch_add(__addr, 1, __ATOMIC_RELAXED);
|
||||
}
|
||||
if (__bare || _M_waiting())
|
||||
_M_cv.notify_all();
|
||||
#endif
|
||||
}
|
||||
|
||||
static __waiter_pool_base&
|
||||
_S_for(const void* __addr) noexcept
|
||||
{
|
||||
constexpr uintptr_t __ct = 16;
|
||||
static __waiter_pool_base __w[__ct];
|
||||
auto __key = (uintptr_t(__addr) >> 2) % __ct;
|
||||
return __w[__key];
|
||||
}
|
||||
};
|
||||
|
||||
struct __waiter_pool : __waiter_pool_base
|
||||
{
|
||||
void
|
||||
_M_do_wait(const __platform_wait_t* __addr, __platform_wait_t __old) noexcept
|
||||
{
|
||||
#ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
|
||||
__platform_wait(__addr, __old);
|
||||
#else
|
||||
__platform_wait_t __val;
|
||||
__atomic_load(__addr, &__val, __ATOMIC_SEQ_CST);
|
||||
if (__val == __old)
|
||||
{
|
||||
lock_guard<mutex> __l(_M_mtx);
|
||||
__atomic_load(__addr, &__val, __ATOMIC_RELAXED);
|
||||
if (__val == __old)
|
||||
_M_cv.wait(_M_mtx);
|
||||
}
|
||||
#endif // __GLIBCXX_HAVE_PLATFORM_WAIT
|
||||
}
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct __waiter_base
|
||||
{
|
||||
using __waiter_type = _Tp;
|
||||
|
||||
__waiter_type& _M_w;
|
||||
__platform_wait_t* _M_addr;
|
||||
|
||||
template<typename _Up>
|
||||
static __platform_wait_t*
|
||||
_S_wait_addr(const _Up* __a, __platform_wait_t* __b)
|
||||
{
|
||||
if constexpr (__platform_wait_uses_type<_Up>)
|
||||
return reinterpret_cast<__platform_wait_t*>(const_cast<_Up*>(__a));
|
||||
else
|
||||
return __b;
|
||||
}
|
||||
|
||||
static __waiter_type&
|
||||
_S_for(const void* __addr) noexcept
|
||||
{
|
||||
static_assert(sizeof(__waiter_type) == sizeof(__waiter_pool_base));
|
||||
auto& res = __waiter_pool_base::_S_for(__addr);
|
||||
return reinterpret_cast<__waiter_type&>(res);
|
||||
}
|
||||
|
||||
template<typename _Up>
|
||||
explicit __waiter_base(const _Up* __addr) noexcept
|
||||
: _M_w(_S_for(__addr))
|
||||
, _M_addr(_S_wait_addr(__addr, &_M_w._M_ver))
|
||||
{ }
|
||||
|
||||
void
|
||||
_M_notify(bool __all, bool __bare = false) noexcept
|
||||
{ _M_w._M_notify(_M_addr, __all, __bare); }
|
||||
|
||||
template<typename _Up, typename _ValFn,
|
||||
typename _Spin = __default_spin_policy>
|
||||
static bool
|
||||
_S_do_spin_v(__platform_wait_t* __addr,
|
||||
const _Up& __old, _ValFn __vfn,
|
||||
__platform_wait_t& __val,
|
||||
_Spin __spin = _Spin{ })
|
||||
{
|
||||
auto const __pred = [=]
|
||||
{ return !__detail::__atomic_compare(__old, __vfn()); };
|
||||
|
||||
if constexpr (__platform_wait_uses_type<_Up>)
|
||||
{
|
||||
__builtin_memcpy(&__val, &__old, sizeof(__val));
|
||||
}
|
||||
else
|
||||
{
|
||||
__atomic_load(__addr, &__val, __ATOMIC_ACQUIRE);
|
||||
}
|
||||
return __atomic_spin(__pred, __spin);
|
||||
}
|
||||
|
||||
template<typename _Up, typename _ValFn,
|
||||
typename _Spin = __default_spin_policy>
|
||||
bool
|
||||
_M_do_spin_v(const _Up& __old, _ValFn __vfn,
|
||||
__platform_wait_t& __val,
|
||||
_Spin __spin = _Spin{ })
|
||||
{ return _S_do_spin_v(_M_addr, __old, __vfn, __val, __spin); }
|
||||
|
||||
template<typename _Pred,
|
||||
typename _Spin = __default_spin_policy>
|
||||
static bool
|
||||
_S_do_spin(const __platform_wait_t* __addr,
|
||||
_Pred __pred,
|
||||
__platform_wait_t& __val,
|
||||
_Spin __spin = _Spin{ })
|
||||
{
|
||||
__atomic_load(__addr, &__val, __ATOMIC_ACQUIRE);
|
||||
return __atomic_spin(__pred, __spin);
|
||||
}
|
||||
|
||||
template<typename _Pred,
|
||||
typename _Spin = __default_spin_policy>
|
||||
bool
|
||||
_M_do_spin(_Pred __pred, __platform_wait_t& __val,
|
||||
_Spin __spin = _Spin{ })
|
||||
{ return _S_do_spin(_M_addr, __pred, __val, __spin); }
|
||||
};
|
||||
|
||||
template<typename _EntersWait>
|
||||
struct __waiter : __waiter_base<__waiter_pool>
|
||||
{
|
||||
using __base_type = __waiter_base<__waiter_pool>;
|
||||
|
||||
template<typename _Tp>
|
||||
explicit __waiter(const _Tp* __addr) noexcept
|
||||
: __base_type(__addr)
|
||||
{
|
||||
if constexpr (_EntersWait::value)
|
||||
_M_w._M_enter_wait();
|
||||
}
|
||||
|
||||
~__waiter()
|
||||
{
|
||||
if constexpr (_EntersWait::value)
|
||||
_M_w._M_leave_wait();
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _ValFn>
|
||||
void
|
||||
_M_do_wait_v(_Tp __old, _ValFn __vfn)
|
||||
{
|
||||
do
|
||||
{
|
||||
__platform_wait_t __val;
|
||||
if (__base_type::_M_do_spin_v(__old, __vfn, __val))
|
||||
return;
|
||||
__base_type::_M_w._M_do_wait(__base_type::_M_addr, __val);
|
||||
}
|
||||
while (__detail::__atomic_compare(__old, __vfn()));
|
||||
}
|
||||
|
||||
template<typename _Pred>
|
||||
void
|
||||
_M_do_wait(_Pred __pred) noexcept
|
||||
{
|
||||
do
|
||||
{
|
||||
__platform_wait_t __val;
|
||||
if (__base_type::_M_do_spin(__pred, __val))
|
||||
return;
|
||||
__base_type::_M_w._M_do_wait(__base_type::_M_addr, __val);
|
||||
}
|
||||
while (!__pred());
|
||||
}
|
||||
};
|
||||
|
||||
using __enters_wait = __waiter<std::true_type>;
|
||||
using __bare_wait = __waiter<std::false_type>;
|
||||
} // namespace __detail
|
||||
|
||||
template<typename _Tp, typename _ValFn>
|
||||
void
|
||||
__atomic_wait_address_v(const _Tp* __addr, _Tp __old,
|
||||
_ValFn __vfn) noexcept
|
||||
{
|
||||
__detail::__enters_wait __w(__addr);
|
||||
__w._M_do_wait_v(__old, __vfn);
|
||||
}
|
||||
|
||||
template<typename _Tp, typename _Pred>
|
||||
void
|
||||
__atomic_wait_address(const _Tp* __addr, _Pred __pred) noexcept
|
||||
{
|
||||
__detail::__enters_wait __w(__addr);
|
||||
__w._M_do_wait(__pred);
|
||||
}
|
||||
|
||||
// This call is to be used by atomic types which track contention externally
|
||||
template<typename _Pred>
|
||||
void
|
||||
__atomic_wait_address_bare(const __detail::__platform_wait_t* __addr,
|
||||
_Pred __pred) noexcept
|
||||
{
|
||||
#ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
|
||||
do
|
||||
{
|
||||
__detail::__platform_wait_t __val;
|
||||
if (__detail::__bare_wait::_S_do_spin(__addr, __pred, __val))
|
||||
return;
|
||||
__detail::__platform_wait(__addr, __val);
|
||||
}
|
||||
while (!__pred());
|
||||
#else // !_GLIBCXX_HAVE_PLATFORM_WAIT
|
||||
__detail::__bare_wait __w(__addr);
|
||||
__w._M_do_wait(__pred);
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename _Tp>
|
||||
void
|
||||
__atomic_notify_address(const _Tp* __addr, bool __all) noexcept
|
||||
{
|
||||
__detail::__bare_wait __w(__addr);
|
||||
__w._M_notify(__all);
|
||||
}
|
||||
|
||||
// This call is to be used by atomic types which track contention externally
|
||||
inline void
|
||||
__atomic_notify_address_bare(const __detail::__platform_wait_t* __addr,
|
||||
bool __all) noexcept
|
||||
{
|
||||
#ifdef _GLIBCXX_HAVE_PLATFORM_WAIT
|
||||
__detail::__platform_notify(__addr, __all);
|
||||
#else
|
||||
__detail::__bare_wait __w(__addr);
|
||||
__w._M_notify(__all, true);
|
||||
#endif
|
||||
}
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // GTHREADS || LINUX_FUTEX
|
||||
#endif // _GLIBCXX_ATOMIC_WAIT_H
|
||||
@@ -0,0 +1,518 @@
|
||||
// Iostreams base classes -*- C++ -*-
|
||||
|
||||
// Copyright (C) 1997-2023 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); }
|
||||
|
||||
// Flips the internal state on for the proper state bits, then
|
||||
// rethrows the propagated exception if bit also set in
|
||||
// exceptions(). Must only be called within a catch handler.
|
||||
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 */
|
||||
@@ -0,0 +1,177 @@
|
||||
// basic_ios member functions -*- C++ -*-
|
||||
|
||||
// Copyright (C) 1999-2023 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 != std::__addressof(__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)
|
||||
{
|
||||
_M_ctype = std::__try_use_facet<__ctype_type>(__loc);
|
||||
_M_num_put = std::__try_use_facet<__num_put_type>(__loc);
|
||||
_M_num_get = std::__try_use_facet<__num_get_type>(__loc);
|
||||
}
|
||||
|
||||
// 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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,883 @@
|
||||
// -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2004-2023 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 std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
_GLIBCXX_BEGIN_NAMESPACE_CONTAINER
|
||||
struct _Bit_iterator;
|
||||
struct _Bit_const_iterator;
|
||||
_GLIBCXX_END_NAMESPACE_CONTAINER
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
}
|
||||
|
||||
namespace __gnu_debug
|
||||
{
|
||||
template<typename _Iterator, typename _Sequence, typename _Category>
|
||||
class _Safe_iterator;
|
||||
}
|
||||
|
||||
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++ = __val(); // require postincrement and assignment
|
||||
}
|
||||
_Tp __i;
|
||||
// Use a function pointer here so no definition of the function needed.
|
||||
// Just need something that returns a _ValueT (which might be a reference).
|
||||
_ValueT (*__val)();
|
||||
};
|
||||
|
||||
template<typename _Tp>
|
||||
struct _Is_vector_bool_iterator
|
||||
{ static const bool __value = false; };
|
||||
|
||||
#ifdef _GLIBCXX_DEBUG
|
||||
namespace __cont = ::std::_GLIBCXX_STD_C;
|
||||
#else
|
||||
namespace __cont = ::std;
|
||||
#endif
|
||||
|
||||
// Trait to identify vector<bool>::iterator
|
||||
template <>
|
||||
struct _Is_vector_bool_iterator<__cont::_Bit_iterator>
|
||||
{ static const bool __value = true; };
|
||||
|
||||
// And for vector<bool>::const_iterator.
|
||||
template <>
|
||||
struct _Is_vector_bool_iterator<__cont::_Bit_const_iterator>
|
||||
{ static const bool __value = true; };
|
||||
|
||||
// And for __gnu_debug::vector<bool> iterators too.
|
||||
template <typename _It, typename _Seq, typename _Tag>
|
||||
struct _Is_vector_bool_iterator<__gnu_debug::_Safe_iterator<_It, _Seq, _Tag> >
|
||||
: _Is_vector_bool_iterator<_It> { };
|
||||
|
||||
template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
|
||||
struct _ForwardIteratorReferenceConcept
|
||||
{
|
||||
void __constraints() {
|
||||
#if __cplusplus >= 201103L
|
||||
typedef typename std::iterator_traits<_Tp>::reference _Ref;
|
||||
static_assert(std::is_reference<_Ref>::value,
|
||||
"reference type of a forward iterator must be a real reference");
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Tp, bool = _Is_vector_bool_iterator<_Tp>::__value>
|
||||
struct _Mutable_ForwardIteratorReferenceConcept
|
||||
{
|
||||
void __constraints() {
|
||||
typedef typename std::iterator_traits<_Tp>::reference _Ref;
|
||||
typedef typename std::iterator_traits<_Tp>::value_type _Val;
|
||||
__function_requires< _SameTypeConcept<_Ref, _Val&> >();
|
||||
}
|
||||
};
|
||||
|
||||
// vector<bool> iterators are not real forward iterators, but we ignore that.
|
||||
template <class _Tp>
|
||||
struct _ForwardIteratorReferenceConcept<_Tp, true>
|
||||
{
|
||||
void __constraints() { }
|
||||
};
|
||||
|
||||
// vector<bool> iterators are not real forward iterators, but we ignore that.
|
||||
template <class _Tp>
|
||||
struct _Mutable_ForwardIteratorReferenceConcept<_Tp, true>
|
||||
{
|
||||
void __constraints() { }
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
|
||||
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> >();
|
||||
__function_requires< _ForwardIteratorReferenceConcept<_Tp> >();
|
||||
_Tp& __j = ++__i;
|
||||
const _Tp& __k = __i++;
|
||||
typedef typename std::iterator_traits<_Tp>::reference _Ref;
|
||||
_Ref __r = *__k;
|
||||
_Ref __r2 = *__i++;
|
||||
}
|
||||
_Tp __i;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct _Mutable_ForwardIteratorConcept
|
||||
{
|
||||
void __constraints() {
|
||||
__function_requires< _ForwardIteratorConcept<_Tp> >();
|
||||
typedef typename std::iterator_traits<_Tp>::reference _Ref;
|
||||
typedef typename std::iterator_traits<_Tp>::value_type _Val;
|
||||
__function_requires< _Mutable_ForwardIteratorReferenceConcept<_Tp> >();
|
||||
}
|
||||
_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> >();
|
||||
_Tp& __j = --__i; // require predecrement operator
|
||||
const _Tp& __k = __i--; // require postdecrement operator
|
||||
typedef typename std::iterator_traits<_Tp>::reference _Ref;
|
||||
_Ref __r = *__j--;
|
||||
}
|
||||
_Tp __i;
|
||||
};
|
||||
|
||||
template <class _Tp>
|
||||
struct _Mutable_BidirectionalIteratorConcept
|
||||
{
|
||||
void __constraints() {
|
||||
__function_requires< _BidirectionalIteratorConcept<_Tp> >();
|
||||
__function_requires< _Mutable_ForwardIteratorConcept<_Tp> >();
|
||||
}
|
||||
_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> >();
|
||||
typedef typename std::iterator_traits<_Tp>::reference _Ref;
|
||||
|
||||
_Tp& __j = __i += __n; // require assignment addition operator
|
||||
__i = __i + __n; __i = __n + __i; // require addition with difference type
|
||||
_Tp& __k = __i -= __n; // require assignment subtraction op
|
||||
__i = __i - __n; // require subtraction with
|
||||
// difference type
|
||||
__n = __i - __j; // require difference operator
|
||||
_Ref __r = __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> >();
|
||||
}
|
||||
_Tp __i;
|
||||
typename std::iterator_traits<_Tp>::difference_type __n;
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
//===========================================================================
|
||||
// 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
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (C) 2007-2023 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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,116 @@
|
||||
// Numeric conversions (to_string, to_chars) -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2017-2023 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>
|
||||
#include <ext/numeric_traits.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
namespace __detail
|
||||
{
|
||||
#if __cpp_variable_templates
|
||||
// This accepts 128-bit integers even in strict mode.
|
||||
template<typename _Tp>
|
||||
constexpr bool __integer_to_chars_is_unsigned
|
||||
= ! __gnu_cxx::__int_traits<_Tp>::__is_signed;
|
||||
#endif
|
||||
|
||||
// Generic implementation for arbitrary bases.
|
||||
template<typename _Tp>
|
||||
_GLIBCXX14_CONSTEXPR unsigned
|
||||
__to_chars_len(_Tp __value, int __base = 10) noexcept
|
||||
{
|
||||
#if __cpp_variable_templates
|
||||
static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
|
||||
#endif
|
||||
|
||||
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>
|
||||
_GLIBCXX23_CONSTEXPR void
|
||||
__to_chars_10_impl(char* __first, unsigned __len, _Tp __val) noexcept
|
||||
{
|
||||
#if __cpp_variable_templates
|
||||
static_assert(__integer_to_chars_is_unsigned<_Tp>, "implementation bug");
|
||||
#endif
|
||||
|
||||
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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,843 @@
|
||||
// Locale support (codecvt) -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2000-2023 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
|
||||
|
||||
#include <bits/c++config.h>
|
||||
#include <bits/locale_classes.h> // locale::facet
|
||||
|
||||
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*, 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*, 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
|
||||
@@ -0,0 +1,81 @@
|
||||
// Concept-checking control -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2023 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)
|
||||
|
||||
#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
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,614 @@
|
||||
// The -*- C++ -*- type traits classes for internal use in libstdc++
|
||||
|
||||
// Copyright (C) 2000-2023 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 __WCHAR_TYPE__
|
||||
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) \
|
||||
__extension__ \
|
||||
template<> \
|
||||
struct __is_integer<TYPE> \
|
||||
{ \
|
||||
enum { __value = 1 }; \
|
||||
typedef __true_type __type; \
|
||||
}; \
|
||||
__extension__ \
|
||||
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;
|
||||
};
|
||||
|
||||
#ifdef __STDCPP_FLOAT16_T__
|
||||
template<>
|
||||
struct __is_floating<_Float16>
|
||||
{
|
||||
enum { __value = 1 };
|
||||
typedef __true_type __type;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __STDCPP_FLOAT32_T__
|
||||
template<>
|
||||
struct __is_floating<_Float32>
|
||||
{
|
||||
enum { __value = 1 };
|
||||
typedef __true_type __type;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __STDCPP_FLOAT64_T__
|
||||
template<>
|
||||
struct __is_floating<_Float64>
|
||||
{
|
||||
enum { __value = 1 };
|
||||
typedef __true_type __type;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __STDCPP_FLOAT128_T__
|
||||
template<>
|
||||
struct __is_floating<_Float128>
|
||||
{
|
||||
enum { __value = 1 };
|
||||
typedef __true_type __type;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __STDCPP_BFLOAT16_T__
|
||||
template<>
|
||||
struct __is_floating<__gnu_cxx::__bfloat16_t>
|
||||
{
|
||||
enum { __value = 1 };
|
||||
typedef __true_type __type;
|
||||
};
|
||||
#endif
|
||||
|
||||
//
|
||||
// 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 __WCHAR_TYPE__
|
||||
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 integer-like types where comparing each byte in turn
|
||||
// as an unsigned char yields the right result. This is true for all
|
||||
// unsigned integers on big endian targets, but only unsigned narrow
|
||||
// character types (and std::byte) on little endian targets.
|
||||
template<typename _Tp, bool _TreatAsBytes =
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
__is_integer<_Tp>::__value
|
||||
#else
|
||||
__is_byte<_Tp>::__value
|
||||
#endif
|
||||
>
|
||||
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
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
// std::byte is not an integer, but it can be compared using memcmp.
|
||||
template<>
|
||||
struct __is_memcmp_ordered<std::byte, false>
|
||||
{ static constexpr bool __value = true; };
|
||||
#endif
|
||||
|
||||
// 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
|
||||
@@ -0,0 +1,60 @@
|
||||
// cxxabi.h subset for cancellation -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2007-2023 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
|
||||
@@ -0,0 +1,81 @@
|
||||
// ABI Support -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2016-2023 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
@@ -0,0 +1,316 @@
|
||||
// <bits/enable_special_members.h> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2013-2023 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
|
||||
|
||||
#include <bits/c++config.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
/// @cond undocumented
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
|
||||
#endif // _ENABLE_SPECIAL_MEMBERS_H
|
||||
@@ -0,0 +1,76 @@
|
||||
// <bits/erase_if.h> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2015-2023 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
|
||||
|
||||
#include <bits/c++config.h>
|
||||
|
||||
namespace std
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
#if __cplusplus > 201703L
|
||||
# define __cpp_lib_erase_if 202002L
|
||||
#endif
|
||||
|
||||
namespace __detail
|
||||
{
|
||||
template<typename _Container, typename _UnsafeContainer,
|
||||
typename _Predicate>
|
||||
typename _Container::size_type
|
||||
__erase_nodes_if(_Container& __cont, _UnsafeContainer& __ucont,
|
||||
_Predicate __pred)
|
||||
{
|
||||
typename _Container::size_type __num = 0;
|
||||
for (auto __iter = __ucont.begin(), __last = __ucont.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
|
||||
@@ -0,0 +1,83 @@
|
||||
// Exception Handling support header for -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2016-2023 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
|
||||
|
||||
#include <bits/c++config.h>
|
||||
|
||||
extern "C++" {
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
/**
|
||||
* @defgroup exceptions Exceptions
|
||||
* @ingroup diagnostics
|
||||
* @since C++98
|
||||
*
|
||||
* 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
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,45 @@
|
||||
// -fno-exceptions Support -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2001-2023 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
|
||||
@@ -0,0 +1,295 @@
|
||||
// Exception Handling support header (exception_ptr class) for -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2008-2023 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
|
||||
|
||||
#include <bits/c++config.h>
|
||||
#include <bits/exception_defines.h>
|
||||
#include <bits/cxxabi_init_exception.h>
|
||||
#include <typeinfo>
|
||||
#include <new>
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
# include <bits/move.h>
|
||||
#endif
|
||||
|
||||
#ifdef _GLIBCXX_EH_PTR_RELOPS_COMPAT
|
||||
# define _GLIBCXX_EH_PTR_USED __attribute__((__used__))
|
||||
#else
|
||||
# define _GLIBCXX_EH_PTR_USED
|
||||
#endif
|
||||
|
||||
extern "C++" {
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
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.
|
||||
*
|
||||
* @since C++11
|
||||
*/
|
||||
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; // So that ADL finds it.
|
||||
|
||||
/**
|
||||
* @brief An opaque pointer to an arbitrary exception.
|
||||
*
|
||||
* The actual name of this type is unspecified, so the alias
|
||||
* `std::exception_ptr` should be used to refer to it.
|
||||
*
|
||||
* @headerfile exception
|
||||
* @since C++11 (but usable in C++98 as a GCC extension)
|
||||
* @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(nullptr)
|
||||
{ }
|
||||
|
||||
exception_ptr(exception_ptr&& __o) noexcept
|
||||
: _M_exception_object(__o._M_exception_object)
|
||||
{ __o._M_exception_object = nullptr; }
|
||||
#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 noexcept
|
||||
{ return _M_exception_object; }
|
||||
#endif
|
||||
|
||||
#if __cpp_impl_three_way_comparison >= 201907L \
|
||||
&& ! defined _GLIBCXX_EH_PTR_RELOPS_COMPAT
|
||||
friend bool
|
||||
operator==(const exception_ptr&, const exception_ptr&) noexcept = default;
|
||||
#else
|
||||
friend _GLIBCXX_EH_PTR_USED bool
|
||||
operator==(const exception_ptr& __x, const exception_ptr& __y)
|
||||
_GLIBCXX_USE_NOEXCEPT
|
||||
{ return __x._M_exception_object == __y._M_exception_object; }
|
||||
|
||||
friend _GLIBCXX_EH_PTR_USED bool
|
||||
operator!=(const exception_ptr& __x, const exception_ptr& __y)
|
||||
_GLIBCXX_USE_NOEXCEPT
|
||||
{ return __x._M_exception_object != __y._M_exception_object; }
|
||||
#endif
|
||||
|
||||
const class std::type_info*
|
||||
__cxa_exception_type() const _GLIBCXX_USE_NOEXCEPT
|
||||
__attribute__ ((__pure__));
|
||||
};
|
||||
|
||||
_GLIBCXX_EH_PTR_USED
|
||||
inline
|
||||
exception_ptr::exception_ptr() _GLIBCXX_USE_NOEXCEPT
|
||||
: _M_exception_object(0)
|
||||
{ }
|
||||
|
||||
_GLIBCXX_EH_PTR_USED
|
||||
inline
|
||||
exception_ptr::exception_ptr(const exception_ptr& __other)
|
||||
_GLIBCXX_USE_NOEXCEPT
|
||||
: _M_exception_object(__other._M_exception_object)
|
||||
{
|
||||
if (_M_exception_object)
|
||||
_M_addref();
|
||||
}
|
||||
|
||||
_GLIBCXX_EH_PTR_USED
|
||||
inline
|
||||
exception_ptr::~exception_ptr() _GLIBCXX_USE_NOEXCEPT
|
||||
{
|
||||
if (_M_exception_object)
|
||||
_M_release();
|
||||
}
|
||||
|
||||
_GLIBCXX_EH_PTR_USED
|
||||
inline exception_ptr&
|
||||
exception_ptr::operator=(const exception_ptr& __other) _GLIBCXX_USE_NOEXCEPT
|
||||
{
|
||||
exception_ptr(__other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
_GLIBCXX_EH_PTR_USED
|
||||
inline void
|
||||
exception_ptr::swap(exception_ptr &__other) _GLIBCXX_USE_NOEXCEPT
|
||||
{
|
||||
void *__tmp = _M_exception_object;
|
||||
_M_exception_object = __other._M_exception_object;
|
||||
__other._M_exception_object = __tmp;
|
||||
}
|
||||
|
||||
/// @relates exception_ptr
|
||||
inline void
|
||||
swap(exception_ptr& __lhs, exception_ptr& __rhs)
|
||||
{ __lhs.swap(__rhs); }
|
||||
|
||||
/// @cond undocumented
|
||||
template<typename _Ex>
|
||||
_GLIBCXX_CDTOR_CALLABI
|
||||
inline void
|
||||
__dest_thunk(void* __x)
|
||||
{ static_cast<_Ex*>(__x)->~_Ex(); }
|
||||
/// @endcond
|
||||
|
||||
} // namespace __exception_ptr
|
||||
|
||||
using __exception_ptr::swap; // So that std::swap(exp1, exp2) finds it.
|
||||
|
||||
/// Obtain an exception_ptr pointing to a copy of the supplied object.
|
||||
#if (__cplusplus >= 201103L && __cpp_rtti) || __cpp_exceptions
|
||||
template<typename _Ex>
|
||||
exception_ptr
|
||||
make_exception_ptr(_Ex __ex) _GLIBCXX_USE_NOEXCEPT
|
||||
{
|
||||
#if __cplusplus >= 201103L && __cpp_rtti
|
||||
using _Ex2 = typename decay<_Ex>::type;
|
||||
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<_Ex2>);
|
||||
__try
|
||||
{
|
||||
::new (__e) _Ex2(__ex);
|
||||
return exception_ptr(__e);
|
||||
}
|
||||
__catch(...)
|
||||
{
|
||||
__cxxabiv1::__cxa_free_exception(__e);
|
||||
return current_exception();
|
||||
}
|
||||
#else
|
||||
try
|
||||
{
|
||||
throw __ex;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
return current_exception();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else // no RTTI and no exceptions
|
||||
// This is always_inline so the linker will never use this useless definition
|
||||
// instead of a working one compiled with RTTI and/or exceptions enabled.
|
||||
template<typename _Ex>
|
||||
__attribute__ ((__always_inline__))
|
||||
inline exception_ptr
|
||||
make_exception_ptr(_Ex) _GLIBCXX_USE_NOEXCEPT
|
||||
{ return exception_ptr(); }
|
||||
#endif
|
||||
|
||||
#undef _GLIBCXX_EH_PTR_USED
|
||||
|
||||
/// @} group exceptions
|
||||
} // namespace std
|
||||
|
||||
} // extern "C++"
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,517 @@
|
||||
// <forward_list.tcc> -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2008-2023 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;
|
||||
forward_list __to_destroy(get_allocator());
|
||||
|
||||
auto __prev_it = cbefore_begin();
|
||||
while (_Node* __tmp = static_cast<_Node*>(__prev_it._M_node->_M_next))
|
||||
if (*__tmp->_M_valptr() == __val)
|
||||
{
|
||||
__to_destroy.splice_after(__to_destroy.cbefore_begin(),
|
||||
*this, __prev_it);
|
||||
_GLIBCXX20_ONLY( __removed++ );
|
||||
}
|
||||
else
|
||||
++__prev_it;
|
||||
|
||||
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;
|
||||
forward_list __to_destroy(get_allocator());
|
||||
|
||||
auto __prev_it = cbefore_begin();
|
||||
while (_Node* __tmp = static_cast<_Node*>(__prev_it._M_node->_M_next))
|
||||
if (__pred(*__tmp->_M_valptr()))
|
||||
{
|
||||
__to_destroy.splice_after(__to_destroy.cbefore_begin(),
|
||||
*this, __prev_it);
|
||||
_GLIBCXX20_ONLY( __removed++ );
|
||||
}
|
||||
else
|
||||
++__prev_it;
|
||||
|
||||
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);
|
||||
|
||||
forward_list __to_destroy(get_allocator());
|
||||
size_type __removed __attribute__((__unused__)) = 0;
|
||||
iterator __next = __first;
|
||||
while (++__next != __last)
|
||||
{
|
||||
if (__binary_pred(*__first, *__next))
|
||||
{
|
||||
__to_destroy.splice_after(__to_destroy.cbefore_begin(),
|
||||
*this, __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)
|
||||
{
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 3088. forward_list::merge behavior unclear when passed *this
|
||||
if (std::__addressof(__list) == this)
|
||||
return;
|
||||
|
||||
_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 */
|
||||
@@ -0,0 +1,634 @@
|
||||
// Filesystem directory utilities -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2014-2023 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 >= 202002L
|
||||
# include <compare> // std::strong_ordering
|
||||
# include <bits/iterator_concepts.h> // std::default_sentinel_t
|
||||
#endif
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
namespace filesystem
|
||||
{
|
||||
/** @addtogroup filesystem
|
||||
* @{
|
||||
*/
|
||||
|
||||
/// Information about a file's type and permissions.
|
||||
/**
|
||||
* @headerfile filesystem
|
||||
* @since C++17
|
||||
*/
|
||||
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
|
||||
/**
|
||||
* @headerfile filesystem
|
||||
* @since C++17
|
||||
*/
|
||||
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 struct _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;
|
||||
};
|
||||
|
||||
/// @cond undocumented
|
||||
|
||||
/// Proxy returned by post-increment on directory iterators.
|
||||
/**
|
||||
* @headerfile filesystem
|
||||
* @since C++17
|
||||
*/
|
||||
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;
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
/// Iterator type for traversing the entries in a single directory.
|
||||
/**
|
||||
* @headerfile filesystem
|
||||
* @since C++17
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 3719. Directory iterators should be usable with default sentinel
|
||||
bool operator==(default_sentinel_t) const noexcept
|
||||
{ return !_M_dir; }
|
||||
#endif
|
||||
|
||||
#if __cpp_impl_three_way_comparison < 201907L
|
||||
friend bool
|
||||
operator!=(const directory_iterator& __lhs,
|
||||
const directory_iterator& __rhs) noexcept
|
||||
{ return !(__lhs == __rhs); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
directory_iterator(const path&, directory_options, error_code*);
|
||||
|
||||
friend class recursive_directory_iterator;
|
||||
|
||||
std::__shared_ptr<_Dir> _M_dir;
|
||||
};
|
||||
|
||||
/** @relates std::filesystem::directory_iterator
|
||||
* @headerfile filesystem
|
||||
* @since C++17
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @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.
|
||||
/**
|
||||
* @headerfile filesystem
|
||||
* @since C++17
|
||||
*/
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||
// 3719. Directory iterators should be usable with default sentinel
|
||||
bool operator==(default_sentinel_t) const noexcept
|
||||
{ return !_M_dirs; }
|
||||
#endif
|
||||
|
||||
#if __cpp_impl_three_way_comparison < 201907L
|
||||
friend bool
|
||||
operator!=(const recursive_directory_iterator& __lhs,
|
||||
const recursive_directory_iterator& __rhs) noexcept
|
||||
{ return !(__lhs == __rhs); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
recursive_directory_iterator(const path&, directory_options, error_code*);
|
||||
|
||||
struct _Dir_stack;
|
||||
std::__shared_ptr<_Dir_stack> _M_dirs;
|
||||
|
||||
recursive_directory_iterator&
|
||||
__erase(error_code* = nullptr);
|
||||
|
||||
friend uintmax_t
|
||||
filesystem::remove_all(const path&, error_code&);
|
||||
friend uintmax_t
|
||||
filesystem::remove_all(const path&);
|
||||
};
|
||||
|
||||
/** @relates std::filesystem::directory_iterator
|
||||
* @headerfile filesystem
|
||||
* @since C++17
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @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
|
||||
@@ -0,0 +1,366 @@
|
||||
// Filesystem declarations -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2014-2023 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 <bits/chrono.h>
|
||||
|
||||
namespace std _GLIBCXX_VISIBILITY(default)
|
||||
{
|
||||
_GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||
|
||||
/// ISO C++ 2017 namespace for File System library
|
||||
namespace filesystem
|
||||
{
|
||||
#if _GLIBCXX_USE_CXX11_ABI
|
||||
/// @cond undocumented
|
||||
inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { }
|
||||
/// @endcond
|
||||
#endif
|
||||
|
||||
/** @addtogroup filesystem
|
||||
* @{
|
||||
*/
|
||||
|
||||
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
|
||||
|
||||
/// Information about free space on a disk
|
||||
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
|
||||
};
|
||||
|
||||
/// Enumerated type representing the type of a file
|
||||
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 controlling effects of `filesystem::copy`
|
||||
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
|
||||
};
|
||||
|
||||
/// @{
|
||||
/// @relates copy_options
|
||||
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 representing file access permissions
|
||||
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,
|
||||
};
|
||||
|
||||
/// @{
|
||||
/// @relates perms
|
||||
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 controlling changes to permissions
|
||||
enum class perm_options : unsigned {
|
||||
replace = 0x1,
|
||||
add = 0x2,
|
||||
remove = 0x4,
|
||||
nofollow = 0x8
|
||||
};
|
||||
|
||||
/// @{
|
||||
/// @relates perm_options
|
||||
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 controlling directory iteration
|
||||
enum class directory_options : unsigned char {
|
||||
none = 0, follow_directory_symlink = 1, skip_permission_denied = 2
|
||||
};
|
||||
|
||||
/// @{
|
||||
/// @relates directory_options
|
||||
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; }
|
||||
/// @}
|
||||
|
||||
/// The type used for file timestamps
|
||||
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;
|
||||
|
||||
bool remove(const path&, error_code&) noexcept;
|
||||
uintmax_t remove_all(const path&);
|
||||
uintmax_t remove_all(const path&, error_code&);
|
||||
|
||||
/// @}
|
||||
} // namespace filesystem
|
||||
_GLIBCXX_END_NAMESPACE_VERSION
|
||||
} // namespace std
|
||||
#endif // C++17
|
||||
#endif // _GLIBCXX_FS_FWD_H
|
||||
@@ -0,0 +1,392 @@
|
||||
// Filesystem operational functions -*- C++ -*-
|
||||
|
||||
// Copyright (C) 2014-2023 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_ops.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
|
||||
* @{
|
||||
*/
|
||||
|
||||
[[nodiscard]]
|
||||
path absolute(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
path absolute(const path& __p, error_code& __ec);
|
||||
|
||||
[[nodiscard]]
|
||||
path canonical(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
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;
|
||||
|
||||
[[nodiscard]]
|
||||
path current_path();
|
||||
|
||||
[[nodiscard]]
|
||||
path current_path(error_code& __ec);
|
||||
|
||||
void current_path(const path& __p);
|
||||
void current_path(const path& __p, error_code& __ec) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
bool
|
||||
equivalent(const path& __p1, const path& __p2);
|
||||
|
||||
[[nodiscard]]
|
||||
bool
|
||||
equivalent(const path& __p1, const path& __p2, error_code& __ec) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
exists(file_status __s) noexcept
|
||||
{ return status_known(__s) && __s.type() != file_type::not_found; }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
exists(const path& __p)
|
||||
{ return exists(status(__p)); }
|
||||
|
||||
[[nodiscard]]
|
||||
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;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
uintmax_t file_size(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
uintmax_t file_size(const path& __p, error_code& __ec) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
uintmax_t hard_link_count(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
uintmax_t hard_link_count(const path& __p, error_code& __ec) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_block_file(file_status __s) noexcept
|
||||
{ return __s.type() == file_type::block; }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_block_file(const path& __p)
|
||||
{ return is_block_file(status(__p)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_block_file(const path& __p, error_code& __ec) noexcept
|
||||
{ return is_block_file(status(__p, __ec)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_character_file(file_status __s) noexcept
|
||||
{ return __s.type() == file_type::character; }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_character_file(const path& __p)
|
||||
{ return is_character_file(status(__p)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_character_file(const path& __p, error_code& __ec) noexcept
|
||||
{ return is_character_file(status(__p, __ec)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_directory(file_status __s) noexcept
|
||||
{ return __s.type() == file_type::directory; }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_directory(const path& __p)
|
||||
{ return is_directory(status(__p)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_directory(const path& __p, error_code& __ec) noexcept
|
||||
{ return is_directory(status(__p, __ec)); }
|
||||
|
||||
[[nodiscard]]
|
||||
bool is_empty(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
bool is_empty(const path& __p, error_code& __ec);
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_fifo(file_status __s) noexcept
|
||||
{ return __s.type() == file_type::fifo; }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_fifo(const path& __p)
|
||||
{ return is_fifo(status(__p)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_fifo(const path& __p, error_code& __ec) noexcept
|
||||
{ return is_fifo(status(__p, __ec)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_other(file_status __s) noexcept
|
||||
{
|
||||
return exists(__s) && !is_regular_file(__s) && !is_directory(__s)
|
||||
&& !is_symlink(__s);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_other(const path& __p)
|
||||
{ return is_other(status(__p)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_other(const path& __p, error_code& __ec) noexcept
|
||||
{ return is_other(status(__p, __ec)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_regular_file(file_status __s) noexcept
|
||||
{ return __s.type() == file_type::regular; }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_regular_file(const path& __p)
|
||||
{ return is_regular_file(status(__p)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_regular_file(const path& __p, error_code& __ec) noexcept
|
||||
{ return is_regular_file(status(__p, __ec)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_socket(file_status __s) noexcept
|
||||
{ return __s.type() == file_type::socket; }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_socket(const path& __p)
|
||||
{ return is_socket(status(__p)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_socket(const path& __p, error_code& __ec) noexcept
|
||||
{ return is_socket(status(__p, __ec)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_symlink(file_status __s) noexcept
|
||||
{ return __s.type() == file_type::symlink; }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_symlink(const path& __p)
|
||||
{ return is_symlink(symlink_status(__p)); }
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool
|
||||
is_symlink(const path& __p, error_code& __ec) noexcept
|
||||
{ return is_symlink(symlink_status(__p, __ec)); }
|
||||
|
||||
[[nodiscard]]
|
||||
file_time_type last_write_time(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
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;
|
||||
|
||||
[[nodiscard]]
|
||||
inline path proximate(const path& __p, error_code& __ec)
|
||||
{ return proximate(__p, current_path(), __ec); }
|
||||
|
||||
[[nodiscard]]
|
||||
path proximate(const path& __p, const path& __base = current_path());
|
||||
|
||||
[[nodiscard]]
|
||||
path proximate(const path& __p, const path& __base, error_code& __ec);
|
||||
|
||||
[[nodiscard]]
|
||||
path read_symlink(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
path read_symlink(const path& __p, error_code& __ec);
|
||||
|
||||
[[nodiscard]]
|
||||
inline path relative(const path& __p, error_code& __ec)
|
||||
{ return relative(__p, current_path(), __ec); }
|
||||
|
||||
[[nodiscard]]
|
||||
path relative(const path& __p, const path& __base = current_path());
|
||||
|
||||
[[nodiscard]]
|
||||
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;
|
||||
|
||||
[[nodiscard]]
|
||||
space_info space(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
space_info space(const path& __p, error_code& __ec) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
file_status status(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
file_status status(const path& __p, error_code& __ec) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
inline bool status_known(file_status __s) noexcept
|
||||
{ return __s.type() != file_type::none; }
|
||||
|
||||
[[nodiscard]]
|
||||
file_status symlink_status(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
file_status symlink_status(const path& __p, error_code& __ec) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
path temp_directory_path();
|
||||
|
||||
[[nodiscard]]
|
||||
path temp_directory_path(error_code& __ec);
|
||||
|
||||
[[nodiscard]]
|
||||
path weakly_canonical(const path& __p);
|
||||
|
||||
[[nodiscard]]
|
||||
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
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user